This notebook documents the process for running the SOT/OTS monthly scripts in R. Preceding these scripts is a SQL procedure and the end output is a collection of .csv files. The following document will demonstrate the process for creating the Master tables and also the output of a single .csv file.
First we need to load our libraries.
The following code will open a system-independent, file chooser using Java and the function created above. It will allow you to choose the directory in which to save all files. This will sometimes fail the first time it is run. If it fails just rerun it (usually works the second time). Note: Eval is set to off to disable dynamic functionality for this notebook. This notebook will use the current working directory instead.
Next we need to create a connection to EDWP. Once you have stored your username and password as my_uid and my_pwd; and created a DSN, connect with a string similar to this (You may need to change the below if you gave your DSN an different name). Then verify that we have successfully connected by performing a query on the dbcinfo table.
Then we create our master tables via query and store them as R objects.
For the purpose of this notebook, however, we will not query the database. Instead, we will load objects already created and stored on the corporate FTP server.
Now let’s download a few static files from Github and save the master objects we just created. We will need these for static mapping.
And create a few tables by joining and summarising.
Lastly we need to output this file as a csv. The file will be output to the directory you set up using the Java file chooser earlier (deactivated for this notebook).
That is it! The basic process is complete. The remaining tables can be created in much the same way.
Appendix
# Create Monthly SOT Brand Table ----
Monthly_Brand_SOT <- SOT_Master %>%
filter(SOT_Master$ShipCancelWeek <= EOW) %>%
group_by(ShipCancelMonth, ReportingBrand) %>%
summarise("SOTUnits" = floor(sum(Units)),
"SOTOnTimeUnits" = floor(sum(Units[Lateness=="OnTime"])),
"SOTLateUnits"= floor(sum(Units[Lateness=="Late"])),
"SOTLate5daysUnits" = floor(sum(Units[Lateness=="Late" & DAYS_LATE > 5])),
"WTSOTLateUnits" = floor(sum(Units[Lateness=="Late"]*DAYS_LATE[Lateness=="Late" & DAYS_LATE >=1])),
"PPAUnits" = floor(sum(Units[SHP_MODE_CATG_NM == "PrepaidAir"])),
"PPASOTLateUnits" = floor(sum(Units[SHP_MODE_CATG_NM == "PrepaidAir" & Lateness=="Late"])),
"PPASOT5daysLateUnits" = floor(sum(Units[SHP_MODE_CATG_NM == "PrepaidAir" & Lateness=="Late" & DAYS_LATE>5])),
"WTPPASOTLateUnits" = floor(sum(Units[SHP_MODE_CATG_NM == "PrepaidAir" & Lateness=="Late"]*DAYS_LATE[SHP_MODE_CATG_NM == "PrepaidAir" & Lateness=="Late" & DAYS_LATE >=1]))) %>%
select(ShipCancelMonth,
ReportingBrand,
SOTUnits,
SOTOnTimeUnits,
SOTLateUnits,
SOTLate5daysUnits,
WTSOTLateUnits,
PPAUnits,
PPASOTLateUnits,
PPASOT5daysLateUnits,
WTPPASOTLateUnits)
# View(Monthly_Brand_SOT)
# Create Monthly SOT Category Table ----
Monthly_Category_SOT <- SOT_Master %>%
filter(SOT_Master$ShipCancelWeek <= EOW) %>%
group_by(ShipCancelMonth, Category) %>%
summarise("SOTUnits" = floor(sum(Units)),
"SOTOnTimeUnits" = floor(sum(Units[Lateness=="OnTime"])),
"SOTLateUnits"= floor(sum(Units[Lateness=="Late"])),
"SOTLate5daysUnits" = floor(sum(Units[Lateness=="Late" & DAYS_LATE > 5])),
"WTSOTLateUnits" = floor(sum(Units[Lateness=="Late"]*DAYS_LATE[Lateness=="Late" & DAYS_LATE >=1])),
"PPAUnits" = floor(sum(Units[SHP_MODE_CATG_NM == "PrepaidAir"])),
"PPASOTLateUnits" = floor(sum(Units[SHP_MODE_CATG_NM == "PrepaidAir" & Lateness=="Late"])),
"PPASOT5daysLateUnits" = floor(sum(Units[SHP_MODE_CATG_NM == "PrepaidAir" & Lateness=="Late" & DAYS_LATE>5])),
"WTPPASOTLateUnits" = floor(sum(Units[SHP_MODE_CATG_NM == "PrepaidAir" & Lateness=="Late"]*DAYS_LATE[SHP_MODE_CATG_NM == "PrepaidAir" & Lateness=="Late" & DAYS_LATE >=1]))) %>%
select(ShipCancelMonth,
Category,
SOTUnits,
SOTOnTimeUnits,
SOTLateUnits,
SOTLate5daysUnits,
WTSOTLateUnits,
PPAUnits,
PPASOTLateUnits,
PPASOT5daysLateUnits,
WTPPASOTLateUnits)
# View(Monthly_Category_SOT)
# Create Monthly Gap Inc SOT Table ----
Monthly_GapInc_SOT <- SOT_Master %>%
filter(SOT_Master$ShipCancelWeek <= EOW) %>%
group_by(ShipCancelMonth) %>%
summarise("SOTUnits" = floor(sum(Units)),
"SOTOnTimeUnits" = floor(sum(Units[Lateness=="OnTime"])),
"SOTLateUnits"= floor(sum(Units[Lateness=="Late"])),
"SOTLate5daysUnits" = floor(sum(Units[Lateness=="Late" & DAYS_LATE > 5])),
"WTSOTLateUnits" = floor(sum(Units[Lateness=="Late"]*DAYS_LATE[Lateness=="Late" & DAYS_LATE >=1])),
"PPAUnits" = floor(sum(Units[SHP_MODE_CATG_NM == "PrepaidAir"])),
"PPASOTLateUnits" = floor(sum(Units[SHP_MODE_CATG_NM == "PrepaidAir" & Lateness=="Late"])),
"PPASOT5daysLateUnits" = floor(sum(Units[SHP_MODE_CATG_NM == "PrepaidAir" & Lateness=="Late" & DAYS_LATE>5])),
"WTPPASOTLateUnits" = floor(sum(Units[SHP_MODE_CATG_NM == "PrepaidAir" & Lateness=="Late"]*DAYS_LATE[SHP_MODE_CATG_NM == "PrepaidAir" & Lateness=="Late" & DAYS_LATE >=1]))) %>%
select(ShipCancelMonth,
SOTUnits,
SOTOnTimeUnits,
SOTLateUnits,
SOTLate5daysUnits,
WTSOTLateUnits,
PPAUnits,
PPASOTLateUnits,
PPASOT5daysLateUnits,
WTPPASOTLateUnits)
# View(Monthly_GapInc_SOT)
# Create Monthly OTS Brand and Category Table ----
Monthly_Brand_Category_OTS <- OTS_Master %>%
filter(OTS_Master$Week <= EOW) %>%
group_by(Month_Number, ReportingBrand, Category) %>%
summarise("OTSUnits" = floor(sum(Units)),
"OTSOnTimeUnits" = floor(sum(Units[Lateness=="OnTime"])),
"OTSLateUnits"= floor(sum(Units[Lateness=="Late"])),
"OTSLate5daysUnits" = floor(sum(Units[Lateness=="Late" & Days_Late > 5])),
"WTOTSLateUnits" = floor(sum(Units[Lateness=="Late"]*Days_Late[Lateness=="Late" & Days_Late >=1])),
"PPAOTSLateUnits" = floor(sum(Units[SHP_MODE_CATG_NM == "PrepaidAir" & Lateness=="Late"]))) %>%
select(Month_Number,
ReportingBrand,
Category,
OTSUnits,
OTSOnTimeUnits,
OTSLateUnits,
OTSLate5daysUnits,
WTOTSLateUnits,
PPAOTSLateUnits)
# View(Monthly_Brand_Category_OTS)
# Create Monthly OTS Brand Table ----
Monthly_Brand_OTS <- OTS_Master %>%
filter(OTS_Master$Week <= EOW) %>%
group_by(Month_Number, ReportingBrand) %>%
summarise("OTSUnits" = floor(sum(Units)),
"OTSOnTimeUnits" = floor(sum(Units[Lateness=="OnTime"])),
"OTSLateUnits"= floor(sum(Units[Lateness=="Late"])),
"OTSLate5daysUnits" = floor(sum(Units[Lateness=="Late" & Days_Late > 5])),
"WTOTSLateUnits" = floor(sum(Units[Lateness=="Late"]*Days_Late[Lateness=="Late" & Days_Late >=1])),
"PPAOTSLateUnits" = floor(sum(Units[SHP_MODE_CATG_NM == "PrepaidAir" & Lateness=="Late"]))) %>%
select(Month_Number,
ReportingBrand,
OTSUnits,
OTSOnTimeUnits,
OTSLateUnits,
OTSLate5daysUnits,
WTOTSLateUnits,
PPAOTSLateUnits)
# View(Monthly_Brand_OTS)
# Create Monthly OTS Category Table ----
Monthly_Category_OTS <- OTS_Master %>%
filter(OTS_Master$Week <= EOW) %>%
group_by(Month_Number, Category) %>%
summarise("OTSUnits" = floor(sum(Units)),
"OTSOnTimeUnits" = floor(sum(Units[Lateness=="OnTime"])),
"OTSLateUnits"= floor(sum(Units[Lateness=="Late"])),
"OTSLate5daysUnits" = floor(sum(Units[Lateness=="Late" & Days_Late > 5])),
"WTOTSLateUnits" = floor(sum(Units[Lateness=="Late"]*Days_Late[Lateness=="Late" & Days_Late >=1])),
"PPAOTSLateUnits" = floor(sum(Units[SHP_MODE_CATG_NM == "PrepaidAir" & Lateness=="Late"]))) %>%
select(Month_Number,
Category,
OTSUnits,
OTSOnTimeUnits,
OTSLateUnits,
OTSLate5daysUnits,
WTOTSLateUnits,
PPAOTSLateUnits)
# View(Monthly_Category_OTS)
# Create Monthly Gap Inc OTS Table ----
Monthly_GapInc_OTS <- OTS_Master %>%
filter(OTS_Master$Week <= EOW) %>%
group_by(Month_Number) %>%
summarise("OTSUnits" = sum(Units),
"OTSOnTimeUnits" = floor(sum(Units[Lateness=="OnTime"])),
"OTSLateUnits"= floor(sum(Units[Lateness=="Late"])),
"OTSLate5daysUnits" = floor(sum(Units[Lateness=="Late" & Days_Late > 5])),
"WTOTSLateUnits" = floor(sum(Units[Lateness=="Late"]*Days_Late[Lateness=="Late" & Days_Late >=1])),
"PPAOTSLateUnits" = floor(sum(Units[SHP_MODE_CATG_NM == "PrepaidAir" & Lateness=="Late"]))) %>%
select(Month_Number,
OTSUnits,
OTSOnTimeUnits,
OTSLateUnits,
OTSLate5daysUnits,
WTOTSLateUnits,
PPAOTSLateUnits)
# View(Monthly_GapInc_OTS)
# Create Monthly - Preferred Vendor - New ----
Monthly_Preferred_Vendor_new <- inner_join(SOT_Master, Preferred_Vendor_new, by = c("Category"= "New Category", "Parent_Vendor"="Vendor Name")) %>%
filter(ShipCancelWeek <= EOW) %>%
group_by(Category, Parent_Vendor, ShipCancelMonth) %>%
summarise("SOTUnits" = floor(sum(Units)),
"SOTOnTimeUnits" = floor(sum(Units[Lateness=="OnTime"])),
"SOTLateUnits"= floor(sum(Units[Lateness=="Late"])),
"SOTLate5daysUnits" = floor(sum(Units[Lateness=="Late" & DAYS_LATE > 5])),
"WTSOTLateUnits" = floor(sum(Units[Lateness=="Late"]*DAYS_LATE[Lateness=="Late" & DAYS_LATE >=1])),
"PPAUnits" = floor(sum(Units[SHP_MODE_CATG_NM == "PrepaidAir"])),
"PPASOTLateUnits" = floor(sum(Units[SHP_MODE_CATG_NM == "PrepaidAir" & Lateness=="Late"])),
"PPASOT5daysLateUnits" = floor(sum(Units[SHP_MODE_CATG_NM == "PrepaidAir" & Lateness=="Late" & DAYS_LATE>5])),
"WTPPASOTLateUnits" = floor(sum(Units[SHP_MODE_CATG_NM == "PrepaidAir" & Lateness=="Late"]*DAYS_LATE[SHP_MODE_CATG_NM == "PrepaidAir" & Lateness=="Late" & DAYS_LATE >=1]))) %>%
select(Category,
Parent_Vendor,
ShipCancelMonth,
SOTUnits,
SOTOnTimeUnits,
SOTLateUnits,
SOTLate5daysUnits,
WTSOTLateUnits,
PPAUnits,
PPASOTLateUnits,
PPASOT5daysLateUnits,
WTPPASOTLateUnits) %>%
arrange(ShipCancelMonth, Category)
# Create Monthly Preferred Vendor - New OTS ----
Monthly_Preferred_Vendor_New_OTS <- inner_join(OTS_Master, Preferred_Vendor_new, by = c("Category"= "New Category", "Parent_Vendor"="Vendor Name")) %>%
filter(Week <= EOW) %>%
group_by(Category, Parent_Vendor, Month_Number ) %>%
summarise("OTSUnits" = floor(sum(Units)),
"OTSOnTimeUnits" = floor(sum(Units[Lateness=="OnTime"])),
"OTSLateUnits"= floor(sum(Units[Lateness=="Late"])),
"OTSLate5daysUnits" = floor(sum(Units[Lateness=="Late" & Days_Late > 5])),
"WTOTSLateUnits" = floor(sum(Units[Lateness=="Late"]*Days_Late[Lateness=="Late" & Days_Late >=1])),
"PPAOTSLateUnits" = floor(sum(Units[SHP_MODE_CATG_NM == "PrepaidAir" & Lateness=="Late"]))) %>%
select(Category,
Parent_Vendor,
Month_Number,
OTSUnits,
OTSOnTimeUnits,
OTSLateUnits,
OTSLate5daysUnits,
WTOTSLateUnits,
PPAOTSLateUnits) %>%
arrange(Month_Number, Category)
# View(Monthly_Preferred_Vendor_New_OTS)
# Create Monthly Brand and Category Combine Table ----
Monthly_Brand_Category_Combine <- left_join(Monthly_Brand_Category_SOT, Monthly_Brand_Category_OTS, by= c("ShipCancelMonth"="Month_Number", "ReportingBrand"="ReportingBrand", "Category"="Category"))
Monthly_Brand_Category_Combine <- Monthly_Brand_Category_Combine[c(1:8, 13:17,9:10,18,11:12)]
# Create Monthly SOT Brand Combine Table ----
Monthly_Brand_Combine <- left_join(Monthly_Brand_SOT, Monthly_Brand_OTS, by= c("ShipCancelMonth"="Month_Number", "ReportingBrand"="ReportingBrand"))
Monthly_Brand_Combine <- Monthly_Brand_Combine[c(1:7, 12:16, 8:9, 17, 10:11)]
# View(Monthly_Brand_Combine)
# Create Monthly SOT Category Combine Table ----
Monthly_Category_Combine <- left_join(Monthly_Category_SOT, Monthly_Category_OTS, by= c("ShipCancelMonth"="Month_Number", "Category"="Category"))
Monthly_Category_Combine <- Monthly_Category_Combine[c(1:7, 12:16, 8:9, 17, 10:11)]
# View(Monthly_Category_Combine)
# Create Monthly SOT Gap Inc Combine Table ----
Monthly_GapInc_Combine <- left_join(Monthly_GapInc_SOT, Monthly_GapInc_OTS, by= c("ShipCancelMonth"="Month_Number"))
Monthly_GapInc_Combine <- Monthly_GapInc_Combine[c(1:6, 11:15,7:8,16,9:10)]
# View(Monthly_GapInc_Combine)
# Create Preferred Vendor Combine Table ----
Preferred_Vendor_New_Combine <- left_join(Monthly_Preferred_Vendor_new, Monthly_Preferred_Vendor_New_OTS, by = c("Category"="Category", "Parent_Vendor"="Parent_Vendor", "ShipCancelMonth" = "Month_Number"))
Preferred_Vendor_New_Combine <-Preferred_Vendor_New_Combine[c(1:8, 13:17, 9:10, 18, 11:12)]
# Create Monthly - byDC
Monthly_by_DC <- OTS_Master %>%
filter(OTS_Master$Week <= EOW) %>%
group_by(Fiscal_Month, Month_Number, DCCampus, DC_NAME, DestCtryCD) %>%
summarise("Total Units" = floor(sum(Units)),
"OnTimeUnits" = floor(sum(Units[Lateness=="OnTime"])),
"OTS%" = sum(Units[Lateness=="OnTime"])/sum(Units),
"OTSLate5daysUnits" = floor(sum(Units[Lateness=="Late" & Days_Late > 5])),
"WTOTSLateUnits" = floor(sum(Units[Lateness=="Late"]*Days_Late[Lateness=="Late" & Days_Late >=1])),
"LateUnits"= floor(sum(Units[Lateness=="Late"]))) %>%
select(Fiscal_Month,
Month_Number,
`OnTimeUnits`,
`Total Units`,
DCCampus,
DC_NAME,
DestCtryCD,
`OTS%`,
`OTSLate5daysUnits`,
`WTOTSLateUnits`,
`LateUnits`)
# Create Top 20 Countries SOT ----
Monthly_Top_20_SOT <- inner_join(SOT_Master, Top_20_Countries, by = c("CountryOfOrigin"= "CountryOfOrigin"))
Monthly_Top_20_SOT <- Monthly_Top_20_SOT %>%
filter(ShipCancelWeek <= EOW) %>%
group_by(ShipCancelMonth) %>%
summarise("SOTUnits" = floor(sum(Units)),
"SOTOnTimeUnits" = floor(sum(Units[Lateness=="OnTime"])),
"SOTLateUnits"= floor(sum(Units[Lateness=="Late"])),
"SOTLate5daysUnits" = floor(sum(Units[Lateness=="Late" & DAYS_LATE > 5])),
"WTSOTLateUnits" = floor(sum(Units[Lateness=="Late"]*DAYS_LATE[Lateness=="Late" & DAYS_LATE >=1])),
"PPAUnits" = floor(sum(Units[SHP_MODE_CATG_NM == "PrepaidAir"])),
"PPASOTLateUnits" = floor(sum(Units[SHP_MODE_CATG_NM == "PrepaidAir" & Lateness=="Late"])),
"PPASOT5daysLateUnits" = floor(sum(Units[SHP_MODE_CATG_NM == "PrepaidAir" & Lateness=="Late" & DAYS_LATE>5])),
"WTPPASOTLateUnits" = floor(sum(Units[SHP_MODE_CATG_NM == "PrepaidAir" & Lateness=="Late"]*DAYS_LATE[SHP_MODE_CATG_NM == "PrepaidAir" & Lateness=="Late" & DAYS_LATE >=1]))) %>%
select(ShipCancelMonth,
SOTUnits,
SOTOnTimeUnits,
SOTLateUnits,
SOTLate5daysUnits,
WTSOTLateUnits,
PPAUnits,
PPASOTLateUnits,
PPASOT5daysLateUnits,
WTPPASOTLateUnits)
# View(Monthly_Top_20_SOT)
# Create Monthly Top 20 OTS Table ----
Monthly_TOP_20_OTS <- inner_join(OTS_Master, Top_20_Countries, by = c("ORIGIN_COUNTRY_CODE"="CountryOfOrigin"))
Monthly_TOP_20_OTS <- Monthly_TOP_20_OTS %>%
filter(Week <= EOW) %>%
group_by(Month_Number) %>%
summarise("OTSUnits" = sum(Units),
"OTSOnTimeUnits" = floor(sum(Units[Lateness=="OnTime"])),
"OTSLateUnits"= floor(sum(Units[Lateness=="Late"])),
"OTSLate5daysUnits" = floor(sum(Units[Lateness=="Late" & Days_Late > 5])),
"WTOTSLateUnits" = floor(sum(Units[Lateness=="Late"]*Days_Late[Lateness=="Late" & Days_Late >=1])),
"PPAOTSLateUnits" = floor(sum(Units[SHP_MODE_CATG_NM == "PrepaidAir" & Lateness=="Late"]))) %>%
select(Month_Number,
OTSUnits,
OTSOnTimeUnits,
OTSLateUnits,
OTSLate5daysUnits,
WTOTSLateUnits,
PPAOTSLateUnits)
# View(Monthly_TOP_20_OTS)
# Create Monthly Top 20 Combine table ----
Monthly_Top_20_Combine <- inner_join(Monthly_Top_20_SOT, Monthly_TOP_20_OTS, by= c("ShipCancelMonth"="Month_Number"))
Monthly_Top_20_Combine <- Monthly_Top_20_Combine[c(1:6, 11:15,7:8,16,9:10)]
# Create Monthly Top 50 Vendors SOT Table ----
Monthly_Top_50_Vendors_SOT <- inner_join(SOT_Master, Top_50_Vendors, by = c("Parent_Vendor"= "Parent_Vendor"))
Monthly_Top_50_Vendors_SOT <- Monthly_Top_50_Vendors_SOT %>%
filter(ShipCancelWeek <= EOW) %>%
group_by(ShipCancelMonth) %>%
summarise("SOTUnits" = floor(sum(Units)),
"SOTOnTimeUnits" = floor(sum(Units[Lateness=="OnTime"])),
"SOTLateUnits"= floor(sum(Units[Lateness=="Late"])),
"SOTLate5daysUnits" = floor(sum(Units[Lateness=="Late" & DAYS_LATE > 5])),
"WTSOTLateUnits" = floor(sum(Units[Lateness=="Late"]*DAYS_LATE[Lateness=="Late" & DAYS_LATE >=1])),
"PPAUnits" = floor(sum(Units[SHP_MODE_CATG_NM == "PrepaidAir"])),
"PPASOTLateUnits" = floor(sum(Units[SHP_MODE_CATG_NM == "PrepaidAir" & Lateness=="Late"])),
"PPASOT5daysLateUnits" = floor(sum(Units[SHP_MODE_CATG_NM == "PrepaidAir" & Lateness=="Late" & DAYS_LATE>5])),
"WTPPASOTLateUnits" = floor(sum(Units[SHP_MODE_CATG_NM == "PrepaidAir" & Lateness=="Late"]*DAYS_LATE[SHP_MODE_CATG_NM == "PrepaidAir" & Lateness=="Late" & DAYS_LATE >=1]))) %>%
select(ShipCancelMonth,
SOTUnits,
SOTOnTimeUnits,
SOTLateUnits,
SOTLate5daysUnits,
WTSOTLateUnits,
PPAUnits,
PPASOTLateUnits,
PPASOT5daysLateUnits,
WTPPASOTLateUnits)
# View(Monthly_Top_50_Vendors_SOT)
# Create Monthly Top 50 Vendors OTS Table ----
Monthly_Top_50_Vendors_OTS <- inner_join(OTS_Master, Top_50_Vendors, by = c("Parent_Vendor"= "Parent_Vendor"))
Monthly_Top_50_Vendors_OTS <- Monthly_Top_50_Vendors_OTS %>%
filter(Week <= EOW) %>%
group_by(Month_Number) %>%
summarise("OTSUnits" = sum(Units),
"OTSOnTimeUnits" = floor(sum(Units[Lateness=="OnTime"])),
"OTSLateUnits"= floor(sum(Units[Lateness=="Late"])),
"OTSLate5daysUnits" = floor(sum(Units[Lateness=="Late" & Days_Late > 5])),
"WTOTSLateUnits" = floor(sum(Units[Lateness=="Late"]*Days_Late[Lateness=="Late" & Days_Late >=1])),
"PPAOTSLateUnits" = floor(sum(Units[SHP_MODE_CATG_NM == "PrepaidAir" & Lateness=="Late"]))) %>%
select(Month_Number,
OTSUnits,
OTSOnTimeUnits,
OTSLateUnits,
OTSLate5daysUnits,
WTOTSLateUnits,
PPAOTSLateUnits)
# View(Monthly_GapInc_OTS)
# Create Monthly SOT Top 50 Vendors Combine Table ----
Monthly_Top_50_Vendors_Combine <- left_join(Monthly_Top_50_Vendors_SOT, Monthly_Top_50_Vendors_OTS, by= c("ShipCancelMonth"="Month_Number"))
Monthly_Top_50_Vendors_Combine <- Monthly_Top_50_Vendors_Combine[c(1:6, 11:15,7:8,16,9:10)]
# View(Monthly_Top_50__Vendors_Combine)
# Create OTSvsSOT table ----
OTS_vs <- OTS_Master %>%
select(NUMBER_SEQ, Month_Number, Lateness, Units) %>%
filter(Lateness!= "Undetermined") %>%
rename("StockedOnTime" = Lateness) %>%
group_by(Month_Number, StockedOnTime) %>%
droplevels()
SOT_vs <- SOT_Master %>%
select(NUMBER_SEQ, ShipCancelMonth, Lateness) %>%
filter(Lateness!="Unmeasured") %>%
rename("ShippedOnTime" = Lateness) %>%
group_by(ShipCancelMonth, ShippedOnTime) %>%
droplevels()
OTSvsSOT <- inner_join(OTS_vs, SOT_vs, by = c("NUMBER_SEQ"= "NUMBER_SEQ")) %>%
group_by(Month_Number, StockedOnTime, ShippedOnTime) %>%
summarise("SumOfUnits" = floor(sum(Units)))
# Create Monthly Brand Top 10 Delay Combine ----
Brand_Top_Ten_Delay <- SOT_Master %>%
filter(ShipCancelWeek <= EOW) %>%
group_by(ReportingBrand, ShipCancelMonth, Parent_Vendor) %>%
summarise("SOTUnits" = floor(sum(Units)),
"AdjustedSOTUnits"= floor(sum(Units[Lateness=="OnTime"]) + sum(Units[Lateness=="Late"])),
"SOTOnTimeUnits" = floor(sum(Units[Lateness=="OnTime"])),
"SOTLateUnits"= floor(sum(Units[Lateness=="Late"])),
"SOTLate5daysUnits" = floor(sum(Units[Lateness=="Late" & DAYS_LATE > 5])),
"WTSOTLateUnits" = floor(sum(Units[Lateness=="Late"]*DAYS_LATE[Lateness=="Late" & DAYS_LATE >=1])),
"PPAUnits" = floor(sum(Units[SHP_MODE_CATG_NM == "PrepaidAir"])),
"PPASOTLateUnits" = floor(sum(Units[SHP_MODE_CATG_NM == "PrepaidAir" & Lateness=="Late"])),
"PPASOT5daysLateUnits" = floor(sum(Units[SHP_MODE_CATG_NM == "PrepaidAir" & Lateness=="Late" & DAYS_LATE>5])),
"WTPPASOTLateUnits" = floor(sum(Units[SHP_MODE_CATG_NM == "PrepaidAir" & Lateness=="Late"]*DAYS_LATE[SHP_MODE_CATG_NM == "PrepaidAir" & Lateness=="Late" & DAYS_LATE >=1]))) %>%
select(
ReportingBrand,
ShipCancelMonth,
Parent_Vendor,
SOTUnits,
AdjustedSOTUnits,
SOTOnTimeUnits,
SOTLateUnits,
SOTLate5daysUnits,
WTSOTLateUnits) %>%
top_n(10, SOTLateUnits) %>%
arrange(ReportingBrand,ShipCancelMonth, desc(SOTLateUnits))
# Create Monthly Category Top 10 Delay Combine ----
Category_Top_Ten_Delay <- SOT_Master %>%
filter(ShipCancelWeek <= EOW) %>%
group_by(Category, ShipCancelMonth, Parent_Vendor) %>%
summarise("SOTUnits" = floor(sum(Units)),
"AdjustedSOTUnits"= floor(sum(Units[Lateness=="OnTime"]) + sum(Units[Lateness=="Late"])),
"SOTOnTimeUnits" = floor(sum(Units[Lateness=="OnTime"])),
"SOTLateUnits"= floor(sum(Units[Lateness=="Late"])),
"SOTLate5daysUnits" = floor(sum(Units[Lateness=="Late" & DAYS_LATE > 5])),
"WTSOTLateUnits" = floor(sum(Units[Lateness=="Late"]*DAYS_LATE[Lateness=="Late" & DAYS_LATE >=1])),
"PPAUnits" = floor(sum(Units[SHP_MODE_CATG_NM == "PrepaidAir"])),
"PPASOTLateUnits" = floor(sum(Units[SHP_MODE_CATG_NM == "PrepaidAir" & Lateness=="Late"])),
"PPASOT5daysLateUnits" = floor(sum(Units[SHP_MODE_CATG_NM == "PrepaidAir" & Lateness=="Late" & DAYS_LATE>5])),
"WTPPASOTLateUnits" = floor(sum(Units[SHP_MODE_CATG_NM == "PrepaidAir" & Lateness=="Late"]*DAYS_LATE[SHP_MODE_CATG_NM == "PrepaidAir" & Lateness=="Late" & DAYS_LATE >=1]))) %>%
select(
Category,
ShipCancelMonth,
Parent_Vendor,
SOTUnits,
AdjustedSOTUnits,
SOTOnTimeUnits,
SOTLateUnits,
SOTLate5daysUnits,
WTSOTLateUnits) %>%
top_n(10, SOTLateUnits) %>%
arrange(Category, ShipCancelMonth, desc(SOTLateUnits))
# Write tables ----
write_csv(Monthly_Brand_Category_Combine,
path = paste(SOT_OTS_directory,
paste('Monthly_Brand_Category_Combine_WE_', EOW, '.csv',sep = ""), sep = '/' ))
write_csv(Monthly_Brand_Combine,
path = paste(SOT_OTS_directory,
paste('Monthly_Brand_Combine_WE_', EOW, '.csv',sep = ""), sep = '/' ))
write_csv(Monthly_Category_Combine,
path = paste(SOT_OTS_directory,
paste('Monthly_Category_Combine_WE_', EOW, '.csv',sep = ""), sep = '/' ))
write_csv(Monthly_GapInc_Combine,
path = paste(SOT_OTS_directory,
paste('Monthly_GapInc_Combine_WE_', EOW, '.csv',sep = ""), sep = '/' ))
write_csv(Preferred_Vendor_New_Combine,
path = paste(SOT_OTS_directory,
paste('Preferred_Vendor_New_Combine_WE_', EOW, '.csv',sep = ""), sep = '/' ))
write_csv(Monthly_by_DC,
path = paste(SOT_OTS_directory,
paste('Monthly_by_DC_WE_', EOW, '.csv',sep = ""), sep = '/' ))
write_csv(Monthly_Top_20_Combine,
path = paste(SOT_OTS_directory,
paste('Monthly_Top_20_Countries_WE_', EOW, '.csv',sep = ""), sep = '/' ))
write_csv(Monthly_Top_50_Vendors_Combine,
path = paste(SOT_OTS_directory,
paste('Monthly_Top_50_Vendors_WE_', EOW, '.csv',sep = ""), sep = '/' ))
write_csv(OTSvsSOT,
path = paste(SOT_OTS_directory,
paste('OTSvsSOT_WE_', EOW, '.csv',sep = ""), sep = '/' ))
write_csv(Brand_Top_Ten_Delay,
path = paste(SOT_OTS_directory,
paste('Brand_Top_10_Delay_WE_', EOW, '.csv',sep = ""), sep = '/' ))
write_csv(Category_Top_Ten_Delay,
path = paste(SOT_OTS_directory,
paste('Category_Top_10_Delay_WE_', EOW, '.csv',sep = ""), sep = '/' ))
LS0tDQp0aXRsZTogIlNPVC9PVFMgTW9udGhseSBOb3RlYm9vayINCm91dHB1dDoNCiAgaHRtbF9ub3RlYm9vazogZGVmYXVsdA0KLS0tDQpUaGlzIG5vdGVib29rIGRvY3VtZW50cyB0aGUgcHJvY2VzcyBmb3IgcnVubmluZyB0aGUgU09UL09UUyBtb250aGx5IHNjcmlwdHMgaW4gUi4gUHJlY2VkaW5nIHRoZXNlIHNjcmlwdHMgaXMgYSBTUUwgcHJvY2VkdXJlIGFuZCB0aGUgZW5kIG91dHB1dCBpcyBhIGNvbGxlY3Rpb24gb2YgLmNzdiBmaWxlcy4gVGhlIGZvbGxvd2luZyBkb2N1bWVudCB3aWxsIGRlbW9uc3RyYXRlIHRoZSBwcm9jZXNzIGZvciBjcmVhdGluZyB0aGUgTWFzdGVyIHRhYmxlcyBhbmQgYWxzbyB0aGUgb3V0cHV0IG9mIGEgc2luZ2xlIC5jc3YgZmlsZS4gDQoNCkZpcnN0IHdlIG5lZWQgdG8gbG9hZCBvdXIgbGlicmFyaWVzLg0KYGBge3Igd2FybmluZz1GQUxTRSwgZXJyb3I9RkFMU0UsIGNvbW1lbnQ9IEZBTFNFfQ0KbGlicmFyeShkcGx5cikNCmxpYnJhcnkocmVhZHIpDQpsaWJyYXJ5KFJPREJDKQ0KbGlicmFyeShmb3JtYXR0YWJsZSkNCmxpYnJhcnkoUkpEQkMpDQpsaWJyYXJ5KHJDaG9pY2VEaWFsb2dzKQ0KbGlicmFyeShSQ3VybCkNCg0KYGBgDQoNClRoZW4gc2V0IHVwIG91ciBFbnZpcm9ubWVudCB3aXRoIGEgZmV3IGZ1bmN0aW9uczoNCmBgYHtyIGV2YWw9RkFMU0V9DQojIHNldHVwIGVudmlyb25tZW50IC0tLS0NCnByb21wdF9mb3Jfd2VlayA8LSBmdW5jdGlvbigpDQp7IA0KICBuIDwtIHJlYWRsaW5lKHByb21wdD0iRW50ZXIgV2VlayBudW1iZXI6ICIpDQogIHJldHVybihhcy5pbnRlZ2VyKG4pKQ0KfQ0KY2hvb3NlX2ZpbGVfZGlyZWN0b3J5IDwtIGZ1bmN0aW9uKCkNCnsNCiAgdiA8LSBqY2hvb3NlLmRpcigpDQogIHJldHVybih2KQ0KfQ0KDQpgYGANCg0KVGhlIGZvbGxvd2luZyBjb2RlIHdpbGwgb3BlbiBhIHN5c3RlbS1pbmRlcGVuZGVudCwgZmlsZSBjaG9vc2VyIHVzaW5nIEphdmEgYW5kIHRoZSBmdW5jdGlvbiBjcmVhdGVkIGFib3ZlLiBJdCB3aWxsIGFsbG93IHlvdSB0byBjaG9vc2UgdGhlIGRpcmVjdG9yeSBpbiB3aGljaCB0byBzYXZlIGFsbCBmaWxlcy4gVGhpcyB3aWxsIHNvbWV0aW1lcyBmYWlsIHRoZSBmaXJzdCB0aW1lIGl0IGlzIHJ1bi4gSWYgaXQgZmFpbHMganVzdCByZXJ1biBpdCAodXN1YWxseSB3b3JrcyB0aGUgc2Vjb25kIHRpbWUpLiBOb3RlOiBFdmFsIGlzIHNldCB0byBvZmYgdG8gZGlzYWJsZSBkeW5hbWljIGZ1bmN0aW9uYWxpdHkgZm9yIHRoaXMgbm90ZWJvb2suIFRoaXMgbm90ZWJvb2sgd2lsbCB1c2UgdGhlIGN1cnJlbnQgd29ya2luZyBkaXJlY3RvcnkgaW5zdGVhZC4gIA0KYGBge3IgZXZhbD1GQUxTRX0NClNPVF9PVFNfZGlyZWN0b3J5IDwtIGNob29zZV9maWxlX2RpcmVjdG9yeSgpDQpgYGANCg0KDQpgYGB7ciBldmFsPUZBTFNFfQ0KRU9XIDwtIHByb21wdF9mb3Jfd2VlaygpDQpgYGANCmBgYHtyIGluY2x1ZGU9RkFMU0V9DQpFT1cgPC0gNDgNCg0KYGBgDQoNCk5leHQgd2UgbmVlZCB0byBjcmVhdGUgYSBjb25uZWN0aW9uIHRvIEVEV1AuIE9uY2UgeW91IGhhdmUgc3RvcmVkIHlvdXIgdXNlcm5hbWUgYW5kIHBhc3N3b3JkIGFzIG15X3VpZCBhbmQgbXlfcHdkOyBhbmQgY3JlYXRlZCBhIERTTiwgY29ubmVjdCB3aXRoIGEgc3RyaW5nIHNpbWlsYXIgdG8gdGhpcyAoWW91IG1heSBuZWVkIHRvIGNoYW5nZSB0aGUgYmVsb3cgaWYgeW91IGdhdmUgeW91ciBEU04gYW4gZGlmZmVyZW50ICBuYW1lKS4gVGhlbiB2ZXJpZnkgdGhhdCB3ZSBoYXZlIHN1Y2Nlc3NmdWxseSBjb25uZWN0ZWQgYnkgcGVyZm9ybWluZyBhIHF1ZXJ5IG9uIHRoZSBkYmNpbmZvIHRhYmxlLg0KYGBge3IgZWNobz1GQUxTRX0NCm15X3VpZCA8LSByZWFkX2xpbmVzKCJDOlxcVXNlcnNcXEtlMmw4YjFcXERvY3VtZW50c1xcbXlfdWlkLnR4dCIpDQpteV9wd2QgPC0gcmVhZF9saW5lcygiQzpcXFVzZXJzXFxLZTJsOGIxXFxEb2N1bWVudHNcXG15X3B3ZC50eHQiKQ0KYGBgDQoNCg0KYGBge3Igd2FybmluZyA9IEZBTFNFfQ0KIyBDcmVhdGUgUk9EQkMgY29ubmVjdGlvbi0tLS0gDQpteV9jb25uZWN0IDwtIG9kYmNDb25uZWN0KGRzbj0gIklQIEVEV1AiLCB1aWQ9IG15X3VpZCwgcHdkPSBteV9wd2QpDQpzcWxRdWVyeShteV9jb25uZWN0LCBxdWVyeSA9ICJTRUxFQ1QgICogZnJvbSBkYmMuZGJjaW5mbzsiKQ0KYGBgDQpXZSBjYW4gc2VlIHRoYXQgdGhlIHNlcnZlciBoYXMgcmV0dXJuZWQgb3VyIHRhYmxlISBXZSBoYXZlIGNvbm5lY3RlZCEgDQoNClRoZW4gd2UgY3JlYXRlIG91ciBtYXN0ZXIgdGFibGVzIHZpYSBxdWVyeSBhbmQgc3RvcmUgdGhlbSBhcyBSIG9iamVjdHMuDQpgYGB7ciBldmFsPUZBTFNFfQ0KIyBRdWVyeSBFRFcgLS0tLQ0KU09UX01hc3RlciA8LSBzcWxRdWVyeShteV9jb25uZWN0LCANCiAgICAgICAgICAgICAgICAgICAgICAgcXVlcnkgPSAiU0VMRUNUICAqIGZyb20gU1JBQV9TQU5ELlZJRVdfU09UX01BU1RFUjsiKQ0KDQpPVFNfTWFzdGVyIDwtIHNxbFF1ZXJ5KG15X2Nvbm5lY3QsIA0KICAgICAgICAgICAgICAgICAgICAgICBxdWVyeSA9ICJTRUxFQ1QgICogZnJvbSBTUkFBX1NBTkQuVklFV19PVFNfTUFTVEVSOyIpDQpjbG9zZShteV9jb25uZWN0KQ0KYGBgDQoNCkZvciB0aGUgcHVycG9zZSBvZiB0aGlzIG5vdGVib29rLCBob3dldmVyLCB3ZSB3aWxsIG5vdCBxdWVyeSB0aGUgZGF0YWJhc2UuIEluc3RlYWQsIHdlIHdpbGwgbG9hZCBvYmplY3RzIGFscmVhZHkgY3JlYXRlZCBhbmQgc3RvcmVkIG9uIHRoZSBjb3Jwb3JhdGUgRlRQIHNlcnZlci4gIA0KYGBge3IgZWNobz1GQUxTRX0NClNPVF9jb25uIDwtIHVybCgiZnRwOi8vZnRwLmdhcC5jb20vZGF0YS90b19ocS9TdXBwbHlDaGFpblJlcG9ydGluZy9HU0NBVC9TT1RNYXN0ZXJPYmplY3RzL1NPVF9NYXN0ZXJfb2JqZWN0LnJ0ZiIpDQpPVFNfY29ubiA8LSB1cmwoImZ0cDovL2Z0cC5nYXAuY29tL2RhdGEvdG9faHEvU3VwcGx5Q2hhaW5SZXBvcnRpbmcvR1NDQVQvU09UTWFzdGVyT2JqZWN0cy9PVFNfTWFzdGVyX29iamVjdC5ydGYiKQ0KIA0KbG9hZChTT1RfY29ubikNCmxvYWQoT1RTX2Nvbm4pDQpgYGANCg0KTm93IGxldCdzIGRvd25sb2FkIGEgZmV3IHN0YXRpYyBmaWxlcyBmcm9tIEdpdGh1YiBhbmQgc2F2ZSB0aGUgbWFzdGVyIG9iamVjdHMgd2UganVzdCBjcmVhdGVkLiBXZSB3aWxsIG5lZWQgdGhlc2UgZm9yIHN0YXRpYyBtYXBwaW5nLiANCmBgYHtyfQ0KIyBJbXBvcnQgc3RhdGljIGZpbGVzIC0tLS0NCnByZWZfY29ubiA8LSBnZXRVUkwoImh0dHBzOi8vcmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbS9HU0NBVC9Nb250aGx5X1NPVC9tYXN0ZXIvUHJlZmVycmVkJTIwVmVuZG9yJTIwKG5ldykuY3N2IikNClByZWZlcnJlZF9WZW5kb3JfbmV3IDwtIHJlYWRfZGVsaW0oZmlsZSA9IHByZWZfY29ubiwgZGVsaW0gPSAiXiIpDQpwcmVmX2Nvbm4gPC0gZ2V0VVJMKCJodHRwczovL3Jhdy5naXRodWJ1c2VyY29udGVudC5jb20vR1NDQVQvTW9udGhseV9TT1QvbWFzdGVyL0NvdW50cnklMjBEZXNjcmlwdGlvbi50eHQiKQ0KQ291bnRyeV9kZXNjcmlwdGlvbiA8LSByZWFkX2RlbGltKGZpbGUgPSBwcmVmX2Nvbm4sIGRlbGltID0gIl4iKQ0KYGBgDQpgYGB7ciBldmFsPUZBTFNFfQ0KIyBzYXZlIE1hc3RlciBPYmplY3RzIC0tLS0NCnNhdmUoU09UX01hc3RlciwgZmlsZSA9IHBhc3RlKFNPVF9PVFNfZGlyZWN0b3J5LCAgJ1NPVF9NYXN0ZXJfb2JqZWN0LnJ0ZicsIHNlcCA9IC5QbGF0Zm9ybSRmaWxlLnNlcCkpDQpzYXZlKE9UU19NYXN0ZXIsIGZpbGUgPSBwYXN0ZShTT1RfT1RTX2RpcmVjdG9yeSwgICdPVFNfTWFzdGVyX29iamVjdC5ydGYnLCBzZXAgPSAuUGxhdGZvcm0kZmlsZS5zZXAgKSkNCmBgYA0KDQpBbmQgY3JlYXRlIGEgZmV3IHRhYmxlcyBieSBqb2luaW5nIGFuZCBzdW1tYXJpc2luZy4NCg0KYGBge3J9DQojIENyZWF0ZSBUT1AgMjAgQ291bnRyaWVzIFRhYmxlIC0tLS0NClRvcF8yMF9Db3VudHJpZXMgPC0gbGVmdF9qb2luKFNPVF9NYXN0ZXIsIENvdW50cnlfZGVzY3JpcHRpb24sIGJ5PSBjKCJDb3VudHJ5T2ZPcmlnaW4iPSJDVFJZX0NEIiApKQ0KVG9wXzIwX0NvdW50cmllcyA8LSBUb3BfMjBfQ291bnRyaWVzICU+JSANCiAgZ3JvdXBfYnkoQ291bnRyeU9mT3JpZ2luLCBDVFJZX0RFU0MpICU+JSANCiAgc3VtbWFyaXNlKCJVbml0cyBieSBDb3VudHJ5IiA9IGZsb29yKHN1bShVbml0cykpKSAlPiUgDQogIGFycmFuZ2UoZGVzYyhgVW5pdHMgYnkgQ291bnRyeWApKSAlPiUgDQogIGhlYWQoMjApIA0KIyBDcmVhdGUgdG9wIDUwIFZlbmRvcnMgLS0tLQ0KVG9wXzUwX1ZlbmRvcnMgPC0gU09UX01hc3RlciAlPiUgDQogIGdyb3VwX2J5KFBhcmVudF9WZW5kb3IpICU+JSANCiAgc3VtbWFyaXNlKCJVbml0cyBieSBWZW5kb3IiID0gZmxvb3Ioc3VtKFVuaXRzKSkpICU+JSANCiAgYXJyYW5nZShkZXNjKGBVbml0cyBieSBWZW5kb3JgKSkgJT4lIA0KICBoZWFkKDUwKQ0KYGBgDQoNCkNoZWNrIHRoZSBmaXJzdCA2IHJvd3Mgb2YgU09UIE1hc3RlciB0byB0ZXN0IHRoYXQgb3VyIGxvYWQoKSB3YXMgc3VjY2Vzc2Z1bDoNCmBgYHtyfQ0KaGVhZChTT1RfTWFzdGVyKQ0KYGBgDQoNCk9uY2Ugd2UgaGF2ZSBvdXIgbWFzdGVyIHRhYmxlcyBhcyBSIG9iamVjdHMgd2UgbmVlZCB0byBjbGVhbiB0aGVtIHVwIGEgYml0Og0KYGBge3J9DQojIFJlbW92ZSBub2lzZSBmcm9tIE9UUyBhbmQgU09UIE1hc3Rlcg0KT1RTX01hc3RlciA8LSBPVFNfTWFzdGVyICU+JSANCiAgZmlsdGVyKFdlZWsgPD0gRU9XLA0KICAgICAgICAgIWdyZXBsKCJMaWJlcnR5IERpc3RyaWJ1dGlvbiIsIFBhcmVudF9WZW5kb3IsIGlnbm9yZS5jYXNlID0gVFJVRSksDQogICAgICAgICAhZ3JlcGwoImR1bW15IiwgUGFyZW50X1ZlbmRvciwgaWdub3JlLmNhc2UgPSBUUlVFKSwNCiAgICAgICAgICFncmVwbCgiSlBGIiwgRENfTkFNRSwgaWdub3JlLmNhc2UgPSBUUlVFKSkgDQoNClNPVF9NYXN0ZXIgPC0gU09UX01hc3RlciAlPiUgDQogIGZpbHRlcihTaGlwQ2FuY2VsV2VlayA8PSBFT1csDQogICAgICAgICAhZ3JlcGwoIkxpYmVydHkgRGlzdHJpYnV0aW9uIiwgUGFyZW50X1ZlbmRvciwgaWdub3JlLmNhc2UgPSBUUlVFKSwNCiAgICAgICAgICFncmVwbCgiZHVtbXkiLCBQYXJlbnRfVmVuZG9yLCBpZ25vcmUuY2FzZSA9IFRSVUUpLA0KICAgICAgICAgTWV0cmljU2hpcERhdGUgPD0gU3lzLkRhdGUoKSkgDQpgYGANCg0KDQpJbiB0aGUgYWN0dWFsIHNjcmlwdCBfTWFzdGVyX0ltcG9ydC5SXyB0aGVyZSBhcmUgbWFueSB0YWJsZXMgdGhhdCBhcmUgZ2VuZXJhdGVkIGZyb20gdGhlIGFib3ZlIE1hc3RlciB0YWJsZXMuIFRoZSBmb2xsb3dpbmcgY29kZSBpcyBhbiBleGFtcGxlIG9mIG9uZSBvdXRwdXQgdGhhdCB3aWxsIGlsbHVzdHJhdGUgdGhlIHByb2Nlc3MgZm9yIGFsbC4gVGhlIHJlbWFpbmluZyBjb2RlIHdpbGwgYmUgcmVzZXJ2ZWQgZm9yIHRoZSBhcHBlbmRpeCBvZiB0aGlzIGRvY3VtZW50Lg0KDQpgYGB7cn0NCk1vbnRobHlfQnJhbmRfQ2F0ZWdvcnlfU09UIDwtIFNPVF9NYXN0ZXIgJT4lDQogIGZpbHRlcihTT1RfTWFzdGVyJFNoaXBDYW5jZWxXZWVrIDw9IEVPVykgJT4lDQogIGdyb3VwX2J5KFNoaXBDYW5jZWxNb250aCwgUmVwb3J0aW5nQnJhbmQsIENhdGVnb3J5KSAlPiUgDQogIHN1bW1hcmlzZSgiU09UVW5pdHMiID0gZmxvb3Ioc3VtKFVuaXRzKSksDQogICAgICAgICAgICAiU09UT25UaW1lVW5pdHMiID0gZmxvb3Ioc3VtKFVuaXRzW0xhdGVuZXNzPT0iT25UaW1lIl0pKSwNCiAgICAgICAgICAgICJTT1RMYXRlVW5pdHMiPSBmbG9vcihzdW0oVW5pdHNbTGF0ZW5lc3M9PSJMYXRlIl0pKSwNCiAgICAgICAgICAgICJTT1RMYXRlNWRheXNVbml0cyIgPSBmbG9vcihzdW0oVW5pdHNbTGF0ZW5lc3M9PSJMYXRlIiAmIERBWVNfTEFURSA+IDVdKSksIA0KICAgICAgICAgICAgIldUU09UTGF0ZVVuaXRzIiA9IGZsb29yKHN1bShVbml0c1tMYXRlbmVzcz09IkxhdGUiXSpEQVlTX0xBVEVbTGF0ZW5lc3M9PSJMYXRlIiAmIERBWVNfTEFURSA+PTFdKSksDQogICAgICAgICAgICAiUFBBVW5pdHMiID0gZmxvb3Ioc3VtKFVuaXRzW1NIUF9NT0RFX0NBVEdfTk0gPT0gIlByZXBhaWRBaXIiXSkpLA0KICAgICAgICAgICAgIlBQQVNPVExhdGVVbml0cyIgPSBmbG9vcihzdW0oVW5pdHNbU0hQX01PREVfQ0FUR19OTSA9PSAiUHJlcGFpZEFpciIgJiBMYXRlbmVzcz09IkxhdGUiXSkpLCANCiAgICAgICAgICAgICJQUEFTT1Q1ZGF5c0xhdGVVbml0cyIgPSBmbG9vcihzdW0oVW5pdHNbU0hQX01PREVfQ0FUR19OTSA9PSAiUHJlcGFpZEFpciIgJiBMYXRlbmVzcz09IkxhdGUiICYgREFZU19MQVRFPjVdKSksDQogICAgICAgICAgICAiV1RQUEFTT1RMYXRlVW5pdHMiID0gZmxvb3Ioc3VtKFVuaXRzW1NIUF9NT0RFX0NBVEdfTk0gPT0gIlByZXBhaWRBaXIiICYgTGF0ZW5lc3M9PSJMYXRlIl0qREFZU19MQVRFW1NIUF9NT0RFX0NBVEdfTk0gPT0gIlByZXBhaWRBaXIiICYgTGF0ZW5lc3M9PSJMYXRlIiAmIERBWVNfTEFURSA+PTFdKSkpICU+JSAgDQogIHNlbGVjdChTaGlwQ2FuY2VsTW9udGgsIA0KICAgICAgICAgUmVwb3J0aW5nQnJhbmQsIA0KICAgICAgICAgQ2F0ZWdvcnksIA0KICAgICAgICAgU09UVW5pdHMsIA0KICAgICAgICAgU09UT25UaW1lVW5pdHMsIA0KICAgICAgICAgU09UTGF0ZVVuaXRzLCANCiAgICAgICAgIFNPVExhdGU1ZGF5c1VuaXRzLCANCiAgICAgICAgIFdUU09UTGF0ZVVuaXRzLCANCiAgICAgICAgIFBQQVVuaXRzLA0KICAgICAgICAgUFBBU09UTGF0ZVVuaXRzLA0KICAgICAgICAgUFBBU09UNWRheXNMYXRlVW5pdHMsDQogICAgICAgICBXVFBQQVNPVExhdGVVbml0cykNCmBgYA0KDQpUYWtpbmcgYSBsb29rIGF0IG91ciBuZXcgdGFibGU6DQoNCmBgYHtyIGVjaG89RkFMU0V9DQpmb3JtYXQoTW9udGhseV9CcmFuZF9DYXRlZ29yeV9TT1Rbc2FtcGxlKDE6bnJvdyhNb250aGx5X0JyYW5kX0NhdGVnb3J5X1NPVCksIDEwKSwgXSwgYmlnLm1hcmsgPSAiLCIpDQpgYGANCg0KTGFzdGx5IHdlIG5lZWQgdG8gb3V0cHV0IHRoaXMgZmlsZSBhcyBhIGNzdi4gVGhlIGZpbGUgd2lsbCBiZSBvdXRwdXQgdG8gdGhlIGRpcmVjdG9yeSB5b3Ugc2V0IHVwIHVzaW5nIHRoZSBKYXZhIGZpbGUgY2hvb3NlciBlYXJsaWVyIChkZWFjdGl2YXRlZCBmb3IgdGhpcyBub3RlYm9vaykuICANCmBgYHtyIGV2YWw9RkFMU0V9DQp3cml0ZV9jc3YoTW9udGhseV9CcmFuZF9DYXRlZ29yeV9Db21iaW5lLCANCiAgICAgICAgICBwYXRoID0gcGFzdGUoU09UX09UU19kaXJlY3RvcnksICANCiAgICAgICAgICAgICAgICAgICAgICAgcGFzdGUoJ01vbnRobHlfQnJhbmRfQ2F0ZWdvcnlfQ29tYmluZV9XRV8nLCBFT1csICcuY3N2JyxzZXAgPSAiIiksIHNlcCA9ICcvJyApKQ0KYGBgDQoNClRoYXQgaXMgaXQhIFRoZSBiYXNpYyBwcm9jZXNzIGlzIGNvbXBsZXRlLiBUaGUgcmVtYWluaW5nIHRhYmxlcyBjYW4gYmUgY3JlYXRlZCBpbiBtdWNoIHRoZSBzYW1lIHdheS4NCg0KXHBhZ2VicmVhaw0KDQojIyBBcHBlbmRpeA0KDQpgYGB7ciBldmFsPUZBTFNFfQ0KIyBDcmVhdGUgTW9udGhseSBTT1QgQnJhbmQgVGFibGUgLS0tLQ0KTW9udGhseV9CcmFuZF9TT1QgPC0gU09UX01hc3RlciAlPiUNCiAgZmlsdGVyKFNPVF9NYXN0ZXIkU2hpcENhbmNlbFdlZWsgPD0gRU9XKSAlPiUNCiAgZ3JvdXBfYnkoU2hpcENhbmNlbE1vbnRoLCBSZXBvcnRpbmdCcmFuZCkgJT4lIA0KICBzdW1tYXJpc2UoIlNPVFVuaXRzIiA9IGZsb29yKHN1bShVbml0cykpLA0KICAgICAgICAgICAgIlNPVE9uVGltZVVuaXRzIiA9IGZsb29yKHN1bShVbml0c1tMYXRlbmVzcz09Ik9uVGltZSJdKSksDQogICAgICAgICAgICAiU09UTGF0ZVVuaXRzIj0gZmxvb3Ioc3VtKFVuaXRzW0xhdGVuZXNzPT0iTGF0ZSJdKSksDQogICAgICAgICAgICAiU09UTGF0ZTVkYXlzVW5pdHMiID0gZmxvb3Ioc3VtKFVuaXRzW0xhdGVuZXNzPT0iTGF0ZSIgJiBEQVlTX0xBVEUgPiA1XSkpLCANCiAgICAgICAgICAgICJXVFNPVExhdGVVbml0cyIgPSBmbG9vcihzdW0oVW5pdHNbTGF0ZW5lc3M9PSJMYXRlIl0qREFZU19MQVRFW0xhdGVuZXNzPT0iTGF0ZSIgJiBEQVlTX0xBVEUgPj0xXSkpLA0KICAgICAgICAgICAgIlBQQVVuaXRzIiA9IGZsb29yKHN1bShVbml0c1tTSFBfTU9ERV9DQVRHX05NID09ICJQcmVwYWlkQWlyIl0pKSwNCiAgICAgICAgICAgICJQUEFTT1RMYXRlVW5pdHMiID0gZmxvb3Ioc3VtKFVuaXRzW1NIUF9NT0RFX0NBVEdfTk0gPT0gIlByZXBhaWRBaXIiICYgTGF0ZW5lc3M9PSJMYXRlIl0pKSwgDQogICAgICAgICAgICAiUFBBU09UNWRheXNMYXRlVW5pdHMiID0gZmxvb3Ioc3VtKFVuaXRzW1NIUF9NT0RFX0NBVEdfTk0gPT0gIlByZXBhaWRBaXIiICYgTGF0ZW5lc3M9PSJMYXRlIiAmIERBWVNfTEFURT41XSkpLA0KICAgICAgICAgICAgIldUUFBBU09UTGF0ZVVuaXRzIiA9IGZsb29yKHN1bShVbml0c1tTSFBfTU9ERV9DQVRHX05NID09ICJQcmVwYWlkQWlyIiAmIExhdGVuZXNzPT0iTGF0ZSJdKkRBWVNfTEFURVtTSFBfTU9ERV9DQVRHX05NID09ICJQcmVwYWlkQWlyIiAmIExhdGVuZXNzPT0iTGF0ZSIgJiBEQVlTX0xBVEUgPj0xXSkpKSAlPiUgIA0KICBzZWxlY3QoU2hpcENhbmNlbE1vbnRoLCANCiAgICAgICAgIFJlcG9ydGluZ0JyYW5kLCANCiAgICAgICAgIFNPVFVuaXRzLCANCiAgICAgICAgIFNPVE9uVGltZVVuaXRzLCANCiAgICAgICAgIFNPVExhdGVVbml0cywgDQogICAgICAgICBTT1RMYXRlNWRheXNVbml0cywgDQogICAgICAgICBXVFNPVExhdGVVbml0cywgDQogICAgICAgICBQUEFVbml0cywNCiAgICAgICAgIFBQQVNPVExhdGVVbml0cywNCiAgICAgICAgIFBQQVNPVDVkYXlzTGF0ZVVuaXRzLA0KICAgICAgICAgV1RQUEFTT1RMYXRlVW5pdHMpDQojIFZpZXcoTW9udGhseV9CcmFuZF9TT1QpDQoNCiMgQ3JlYXRlIE1vbnRobHkgU09UIENhdGVnb3J5IFRhYmxlIC0tLS0NCk1vbnRobHlfQ2F0ZWdvcnlfU09UIDwtIFNPVF9NYXN0ZXIgJT4lDQogIGZpbHRlcihTT1RfTWFzdGVyJFNoaXBDYW5jZWxXZWVrIDw9IEVPVykgJT4lDQogIGdyb3VwX2J5KFNoaXBDYW5jZWxNb250aCwgQ2F0ZWdvcnkpICU+JSANCiAgc3VtbWFyaXNlKCJTT1RVbml0cyIgPSBmbG9vcihzdW0oVW5pdHMpKSwNCiAgICAgICAgICAgICJTT1RPblRpbWVVbml0cyIgPSBmbG9vcihzdW0oVW5pdHNbTGF0ZW5lc3M9PSJPblRpbWUiXSkpLA0KICAgICAgICAgICAgIlNPVExhdGVVbml0cyI9IGZsb29yKHN1bShVbml0c1tMYXRlbmVzcz09IkxhdGUiXSkpLA0KICAgICAgICAgICAgIlNPVExhdGU1ZGF5c1VuaXRzIiA9IGZsb29yKHN1bShVbml0c1tMYXRlbmVzcz09IkxhdGUiICYgREFZU19MQVRFID4gNV0pKSwgDQogICAgICAgICAgICAiV1RTT1RMYXRlVW5pdHMiID0gZmxvb3Ioc3VtKFVuaXRzW0xhdGVuZXNzPT0iTGF0ZSJdKkRBWVNfTEFURVtMYXRlbmVzcz09IkxhdGUiICYgREFZU19MQVRFID49MV0pKSwNCiAgICAgICAgICAgICJQUEFVbml0cyIgPSBmbG9vcihzdW0oVW5pdHNbU0hQX01PREVfQ0FUR19OTSA9PSAiUHJlcGFpZEFpciJdKSksDQogICAgICAgICAgICAiUFBBU09UTGF0ZVVuaXRzIiA9IGZsb29yKHN1bShVbml0c1tTSFBfTU9ERV9DQVRHX05NID09ICJQcmVwYWlkQWlyIiAmIExhdGVuZXNzPT0iTGF0ZSJdKSksIA0KICAgICAgICAgICAgIlBQQVNPVDVkYXlzTGF0ZVVuaXRzIiA9IGZsb29yKHN1bShVbml0c1tTSFBfTU9ERV9DQVRHX05NID09ICJQcmVwYWlkQWlyIiAmIExhdGVuZXNzPT0iTGF0ZSIgJiBEQVlTX0xBVEU+NV0pKSwNCiAgICAgICAgICAgICJXVFBQQVNPVExhdGVVbml0cyIgPSBmbG9vcihzdW0oVW5pdHNbU0hQX01PREVfQ0FUR19OTSA9PSAiUHJlcGFpZEFpciIgJiBMYXRlbmVzcz09IkxhdGUiXSpEQVlTX0xBVEVbU0hQX01PREVfQ0FUR19OTSA9PSAiUHJlcGFpZEFpciIgJiBMYXRlbmVzcz09IkxhdGUiICYgREFZU19MQVRFID49MV0pKSkgJT4lICANCiAgc2VsZWN0KFNoaXBDYW5jZWxNb250aCwgDQogICAgICAgICBDYXRlZ29yeSwgDQogICAgICAgICBTT1RVbml0cywgDQogICAgICAgICBTT1RPblRpbWVVbml0cywgDQogICAgICAgICBTT1RMYXRlVW5pdHMsIA0KICAgICAgICAgU09UTGF0ZTVkYXlzVW5pdHMsIA0KICAgICAgICAgV1RTT1RMYXRlVW5pdHMsIA0KICAgICAgICAgUFBBVW5pdHMsDQogICAgICAgICBQUEFTT1RMYXRlVW5pdHMsDQogICAgICAgICBQUEFTT1Q1ZGF5c0xhdGVVbml0cywNCiAgICAgICAgIFdUUFBBU09UTGF0ZVVuaXRzKQ0KIyBWaWV3KE1vbnRobHlfQ2F0ZWdvcnlfU09UKSANCg0KIyBDcmVhdGUgTW9udGhseSBHYXAgSW5jIFNPVCBUYWJsZSAtLS0tDQpNb250aGx5X0dhcEluY19TT1QgPC0gU09UX01hc3RlciAlPiUNCiAgZmlsdGVyKFNPVF9NYXN0ZXIkU2hpcENhbmNlbFdlZWsgPD0gRU9XKSAlPiUNCiAgZ3JvdXBfYnkoU2hpcENhbmNlbE1vbnRoKSAlPiUgDQogIHN1bW1hcmlzZSgiU09UVW5pdHMiID0gZmxvb3Ioc3VtKFVuaXRzKSksDQogICAgICAgICAgICAiU09UT25UaW1lVW5pdHMiID0gZmxvb3Ioc3VtKFVuaXRzW0xhdGVuZXNzPT0iT25UaW1lIl0pKSwNCiAgICAgICAgICAgICJTT1RMYXRlVW5pdHMiPSBmbG9vcihzdW0oVW5pdHNbTGF0ZW5lc3M9PSJMYXRlIl0pKSwNCiAgICAgICAgICAgICJTT1RMYXRlNWRheXNVbml0cyIgPSBmbG9vcihzdW0oVW5pdHNbTGF0ZW5lc3M9PSJMYXRlIiAmIERBWVNfTEFURSA+IDVdKSksIA0KICAgICAgICAgICAgIldUU09UTGF0ZVVuaXRzIiA9IGZsb29yKHN1bShVbml0c1tMYXRlbmVzcz09IkxhdGUiXSpEQVlTX0xBVEVbTGF0ZW5lc3M9PSJMYXRlIiAmIERBWVNfTEFURSA+PTFdKSksDQogICAgICAgICAgICAiUFBBVW5pdHMiID0gZmxvb3Ioc3VtKFVuaXRzW1NIUF9NT0RFX0NBVEdfTk0gPT0gIlByZXBhaWRBaXIiXSkpLA0KICAgICAgICAgICAgIlBQQVNPVExhdGVVbml0cyIgPSBmbG9vcihzdW0oVW5pdHNbU0hQX01PREVfQ0FUR19OTSA9PSAiUHJlcGFpZEFpciIgJiBMYXRlbmVzcz09IkxhdGUiXSkpLCANCiAgICAgICAgICAgICJQUEFTT1Q1ZGF5c0xhdGVVbml0cyIgPSBmbG9vcihzdW0oVW5pdHNbU0hQX01PREVfQ0FUR19OTSA9PSAiUHJlcGFpZEFpciIgJiBMYXRlbmVzcz09IkxhdGUiICYgREFZU19MQVRFPjVdKSksDQogICAgICAgICAgICAiV1RQUEFTT1RMYXRlVW5pdHMiID0gZmxvb3Ioc3VtKFVuaXRzW1NIUF9NT0RFX0NBVEdfTk0gPT0gIlByZXBhaWRBaXIiICYgTGF0ZW5lc3M9PSJMYXRlIl0qREFZU19MQVRFW1NIUF9NT0RFX0NBVEdfTk0gPT0gIlByZXBhaWRBaXIiICYgTGF0ZW5lc3M9PSJMYXRlIiAmIERBWVNfTEFURSA+PTFdKSkpICU+JSAgDQogIHNlbGVjdChTaGlwQ2FuY2VsTW9udGgsIA0KICAgICAgICAgU09UVW5pdHMsIA0KICAgICAgICAgU09UT25UaW1lVW5pdHMsIA0KICAgICAgICAgU09UTGF0ZVVuaXRzLCANCiAgICAgICAgIFNPVExhdGU1ZGF5c1VuaXRzLCANCiAgICAgICAgIFdUU09UTGF0ZVVuaXRzLCANCiAgICAgICAgIFBQQVVuaXRzLA0KICAgICAgICAgUFBBU09UTGF0ZVVuaXRzLA0KICAgICAgICAgUFBBU09UNWRheXNMYXRlVW5pdHMsDQogICAgICAgICBXVFBQQVNPVExhdGVVbml0cykNCiMgVmlldyhNb250aGx5X0dhcEluY19TT1QpIA0KDQojIENyZWF0ZSBNb250aGx5IE9UUyBCcmFuZCBhbmQgQ2F0ZWdvcnkgVGFibGUgLS0tLQ0KTW9udGhseV9CcmFuZF9DYXRlZ29yeV9PVFMgPC0gT1RTX01hc3RlciAlPiUNCiAgZmlsdGVyKE9UU19NYXN0ZXIkV2VlayA8PSBFT1cpICU+JQ0KICBncm91cF9ieShNb250aF9OdW1iZXIsIFJlcG9ydGluZ0JyYW5kLCBDYXRlZ29yeSkgJT4lIA0KICBzdW1tYXJpc2UoIk9UU1VuaXRzIiA9IGZsb29yKHN1bShVbml0cykpLA0KICAgICAgICAgICAgIk9UU09uVGltZVVuaXRzIiA9IGZsb29yKHN1bShVbml0c1tMYXRlbmVzcz09Ik9uVGltZSJdKSksDQogICAgICAgICAgICAiT1RTTGF0ZVVuaXRzIj0gZmxvb3Ioc3VtKFVuaXRzW0xhdGVuZXNzPT0iTGF0ZSJdKSksDQogICAgICAgICAgICAiT1RTTGF0ZTVkYXlzVW5pdHMiID0gZmxvb3Ioc3VtKFVuaXRzW0xhdGVuZXNzPT0iTGF0ZSIgJiBEYXlzX0xhdGUgPiA1XSkpLCANCiAgICAgICAgICAgICJXVE9UU0xhdGVVbml0cyIgPSBmbG9vcihzdW0oVW5pdHNbTGF0ZW5lc3M9PSJMYXRlIl0qRGF5c19MYXRlW0xhdGVuZXNzPT0iTGF0ZSIgJiBEYXlzX0xhdGUgPj0xXSkpLA0KICAgICAgICAgICAgIlBQQU9UU0xhdGVVbml0cyIgPSBmbG9vcihzdW0oVW5pdHNbU0hQX01PREVfQ0FUR19OTSA9PSAiUHJlcGFpZEFpciIgJiBMYXRlbmVzcz09IkxhdGUiXSkpKSAlPiUgIA0KICBzZWxlY3QoTW9udGhfTnVtYmVyLCANCiAgICAgICAgIFJlcG9ydGluZ0JyYW5kLCANCiAgICAgICAgIENhdGVnb3J5LCANCiAgICAgICAgIE9UU1VuaXRzLCANCiAgICAgICAgIE9UU09uVGltZVVuaXRzLCANCiAgICAgICAgIE9UU0xhdGVVbml0cywgDQogICAgICAgICBPVFNMYXRlNWRheXNVbml0cywgDQogICAgICAgICBXVE9UU0xhdGVVbml0cywgDQogICAgICAgICBQUEFPVFNMYXRlVW5pdHMpDQogIyBWaWV3KE1vbnRobHlfQnJhbmRfQ2F0ZWdvcnlfT1RTKQ0KDQojIENyZWF0ZSBNb250aGx5IE9UUyBCcmFuZCBUYWJsZSAtLS0tDQpNb250aGx5X0JyYW5kX09UUyA8LSBPVFNfTWFzdGVyICU+JQ0KICBmaWx0ZXIoT1RTX01hc3RlciRXZWVrIDw9IEVPVykgJT4lDQogIGdyb3VwX2J5KE1vbnRoX051bWJlciwgUmVwb3J0aW5nQnJhbmQpICU+JSANCiAgc3VtbWFyaXNlKCJPVFNVbml0cyIgPSBmbG9vcihzdW0oVW5pdHMpKSwNCiAgICAgICAgICAgICJPVFNPblRpbWVVbml0cyIgPSBmbG9vcihzdW0oVW5pdHNbTGF0ZW5lc3M9PSJPblRpbWUiXSkpLA0KICAgICAgICAgICAgIk9UU0xhdGVVbml0cyI9IGZsb29yKHN1bShVbml0c1tMYXRlbmVzcz09IkxhdGUiXSkpLA0KICAgICAgICAgICAgIk9UU0xhdGU1ZGF5c1VuaXRzIiA9IGZsb29yKHN1bShVbml0c1tMYXRlbmVzcz09IkxhdGUiICYgRGF5c19MYXRlID4gNV0pKSwgDQogICAgICAgICAgICAiV1RPVFNMYXRlVW5pdHMiID0gZmxvb3Ioc3VtKFVuaXRzW0xhdGVuZXNzPT0iTGF0ZSJdKkRheXNfTGF0ZVtMYXRlbmVzcz09IkxhdGUiICYgRGF5c19MYXRlID49MV0pKSwNCiAgICAgICAgICAgICJQUEFPVFNMYXRlVW5pdHMiID0gZmxvb3Ioc3VtKFVuaXRzW1NIUF9NT0RFX0NBVEdfTk0gPT0gIlByZXBhaWRBaXIiICYgTGF0ZW5lc3M9PSJMYXRlIl0pKSkgJT4lICANCiAgc2VsZWN0KE1vbnRoX051bWJlciwgDQogICAgICAgICBSZXBvcnRpbmdCcmFuZCwgDQogICAgICAgICBPVFNVbml0cywgDQogICAgICAgICBPVFNPblRpbWVVbml0cywgDQogICAgICAgICBPVFNMYXRlVW5pdHMsIA0KICAgICAgICAgT1RTTGF0ZTVkYXlzVW5pdHMsIA0KICAgICAgICAgV1RPVFNMYXRlVW5pdHMsIA0KICAgICAgICAgUFBBT1RTTGF0ZVVuaXRzKQ0KIyBWaWV3KE1vbnRobHlfQnJhbmRfT1RTKQ0KDQojIENyZWF0ZSBNb250aGx5IE9UUyBDYXRlZ29yeSBUYWJsZSAtLS0tDQpNb250aGx5X0NhdGVnb3J5X09UUyA8LSBPVFNfTWFzdGVyICU+JQ0KICBmaWx0ZXIoT1RTX01hc3RlciRXZWVrIDw9IEVPVykgJT4lDQogIGdyb3VwX2J5KE1vbnRoX051bWJlciwgQ2F0ZWdvcnkpICU+JSANCiAgc3VtbWFyaXNlKCJPVFNVbml0cyIgPSBmbG9vcihzdW0oVW5pdHMpKSwNCiAgICAgICAgICAgICJPVFNPblRpbWVVbml0cyIgPSBmbG9vcihzdW0oVW5pdHNbTGF0ZW5lc3M9PSJPblRpbWUiXSkpLA0KICAgICAgICAgICAgIk9UU0xhdGVVbml0cyI9IGZsb29yKHN1bShVbml0c1tMYXRlbmVzcz09IkxhdGUiXSkpLA0KICAgICAgICAgICAgIk9UU0xhdGU1ZGF5c1VuaXRzIiA9IGZsb29yKHN1bShVbml0c1tMYXRlbmVzcz09IkxhdGUiICYgRGF5c19MYXRlID4gNV0pKSwgDQogICAgICAgICAgICAiV1RPVFNMYXRlVW5pdHMiID0gZmxvb3Ioc3VtKFVuaXRzW0xhdGVuZXNzPT0iTGF0ZSJdKkRheXNfTGF0ZVtMYXRlbmVzcz09IkxhdGUiICYgRGF5c19MYXRlID49MV0pKSwNCiAgICAgICAgICAgICJQUEFPVFNMYXRlVW5pdHMiID0gZmxvb3Ioc3VtKFVuaXRzW1NIUF9NT0RFX0NBVEdfTk0gPT0gIlByZXBhaWRBaXIiICYgTGF0ZW5lc3M9PSJMYXRlIl0pKSkgJT4lICANCiAgc2VsZWN0KE1vbnRoX051bWJlciwgDQogICAgICAgICBDYXRlZ29yeSwgDQogICAgICAgICBPVFNVbml0cywgDQogICAgICAgICBPVFNPblRpbWVVbml0cywgDQogICAgICAgICBPVFNMYXRlVW5pdHMsIA0KICAgICAgICAgT1RTTGF0ZTVkYXlzVW5pdHMsIA0KICAgICAgICAgV1RPVFNMYXRlVW5pdHMsIA0KICAgICAgICAgUFBBT1RTTGF0ZVVuaXRzKQ0KIyBWaWV3KE1vbnRobHlfQ2F0ZWdvcnlfT1RTKQ0KDQojIENyZWF0ZSBNb250aGx5IEdhcCBJbmMgT1RTIFRhYmxlIC0tLS0NCk1vbnRobHlfR2FwSW5jX09UUyA8LSBPVFNfTWFzdGVyICU+JQ0KICBmaWx0ZXIoT1RTX01hc3RlciRXZWVrIDw9IEVPVykgJT4lDQogIGdyb3VwX2J5KE1vbnRoX051bWJlcikgJT4lIA0KICBzdW1tYXJpc2UoIk9UU1VuaXRzIiA9IHN1bShVbml0cyksDQogICAgICAgICAgICAiT1RTT25UaW1lVW5pdHMiID0gZmxvb3Ioc3VtKFVuaXRzW0xhdGVuZXNzPT0iT25UaW1lIl0pKSwNCiAgICAgICAgICAgICJPVFNMYXRlVW5pdHMiPSBmbG9vcihzdW0oVW5pdHNbTGF0ZW5lc3M9PSJMYXRlIl0pKSwNCiAgICAgICAgICAgICJPVFNMYXRlNWRheXNVbml0cyIgPSBmbG9vcihzdW0oVW5pdHNbTGF0ZW5lc3M9PSJMYXRlIiAmIERheXNfTGF0ZSA+IDVdKSksIA0KICAgICAgICAgICAgIldUT1RTTGF0ZVVuaXRzIiA9IGZsb29yKHN1bShVbml0c1tMYXRlbmVzcz09IkxhdGUiXSpEYXlzX0xhdGVbTGF0ZW5lc3M9PSJMYXRlIiAmIERheXNfTGF0ZSA+PTFdKSksDQogICAgICAgICAgICAiUFBBT1RTTGF0ZVVuaXRzIiA9IGZsb29yKHN1bShVbml0c1tTSFBfTU9ERV9DQVRHX05NID09ICJQcmVwYWlkQWlyIiAmIExhdGVuZXNzPT0iTGF0ZSJdKSkpICU+JSAgDQogIHNlbGVjdChNb250aF9OdW1iZXIsIA0KICAgICAgICAgT1RTVW5pdHMsIA0KICAgICAgICAgT1RTT25UaW1lVW5pdHMsIA0KICAgICAgICAgT1RTTGF0ZVVuaXRzLCANCiAgICAgICAgIE9UU0xhdGU1ZGF5c1VuaXRzLCANCiAgICAgICAgIFdUT1RTTGF0ZVVuaXRzLCANCiAgICAgICAgIFBQQU9UU0xhdGVVbml0cykNCiAjIFZpZXcoTW9udGhseV9HYXBJbmNfT1RTKQ0KDQojIENyZWF0ZSBNb250aGx5IC0gUHJlZmVycmVkIFZlbmRvciAtIE5ldyAtLS0tDQpNb250aGx5X1ByZWZlcnJlZF9WZW5kb3JfbmV3IDwtIGlubmVyX2pvaW4oU09UX01hc3RlciwgUHJlZmVycmVkX1ZlbmRvcl9uZXcsIGJ5ID0gYygiQ2F0ZWdvcnkiPSAiTmV3IENhdGVnb3J5IiwgIlBhcmVudF9WZW5kb3IiPSJWZW5kb3IgTmFtZSIpKSAlPiUgDQogIGZpbHRlcihTaGlwQ2FuY2VsV2VlayA8PSBFT1cpICU+JQ0KICBncm91cF9ieShDYXRlZ29yeSwgUGFyZW50X1ZlbmRvciwgU2hpcENhbmNlbE1vbnRoKSAlPiUgDQogIHN1bW1hcmlzZSgiU09UVW5pdHMiID0gZmxvb3Ioc3VtKFVuaXRzKSksDQogICAgICAgICAgICAiU09UT25UaW1lVW5pdHMiID0gZmxvb3Ioc3VtKFVuaXRzW0xhdGVuZXNzPT0iT25UaW1lIl0pKSwNCiAgICAgICAgICAgICJTT1RMYXRlVW5pdHMiPSBmbG9vcihzdW0oVW5pdHNbTGF0ZW5lc3M9PSJMYXRlIl0pKSwNCiAgICAgICAgICAgICJTT1RMYXRlNWRheXNVbml0cyIgPSBmbG9vcihzdW0oVW5pdHNbTGF0ZW5lc3M9PSJMYXRlIiAmIERBWVNfTEFURSA+IDVdKSksIA0KICAgICAgICAgICAgIldUU09UTGF0ZVVuaXRzIiA9IGZsb29yKHN1bShVbml0c1tMYXRlbmVzcz09IkxhdGUiXSpEQVlTX0xBVEVbTGF0ZW5lc3M9PSJMYXRlIiAmIERBWVNfTEFURSA+PTFdKSksDQogICAgICAgICAgICAiUFBBVW5pdHMiID0gZmxvb3Ioc3VtKFVuaXRzW1NIUF9NT0RFX0NBVEdfTk0gPT0gIlByZXBhaWRBaXIiXSkpLA0KICAgICAgICAgICAgIlBQQVNPVExhdGVVbml0cyIgPSBmbG9vcihzdW0oVW5pdHNbU0hQX01PREVfQ0FUR19OTSA9PSAiUHJlcGFpZEFpciIgJiBMYXRlbmVzcz09IkxhdGUiXSkpLCANCiAgICAgICAgICAgICJQUEFTT1Q1ZGF5c0xhdGVVbml0cyIgPSBmbG9vcihzdW0oVW5pdHNbU0hQX01PREVfQ0FUR19OTSA9PSAiUHJlcGFpZEFpciIgJiBMYXRlbmVzcz09IkxhdGUiICYgREFZU19MQVRFPjVdKSksDQogICAgICAgICAgICAiV1RQUEFTT1RMYXRlVW5pdHMiID0gZmxvb3Ioc3VtKFVuaXRzW1NIUF9NT0RFX0NBVEdfTk0gPT0gIlByZXBhaWRBaXIiICYgTGF0ZW5lc3M9PSJMYXRlIl0qREFZU19MQVRFW1NIUF9NT0RFX0NBVEdfTk0gPT0gIlByZXBhaWRBaXIiICYgTGF0ZW5lc3M9PSJMYXRlIiAmIERBWVNfTEFURSA+PTFdKSkpICU+JSAgDQogIHNlbGVjdChDYXRlZ29yeSwNCiAgICAgICAgIFBhcmVudF9WZW5kb3IsDQogICAgICAgICBTaGlwQ2FuY2VsTW9udGgsDQogICAgICAgICBTT1RVbml0cywgDQogICAgICAgICBTT1RPblRpbWVVbml0cywgDQogICAgICAgICBTT1RMYXRlVW5pdHMsIA0KICAgICAgICAgU09UTGF0ZTVkYXlzVW5pdHMsIA0KICAgICAgICAgV1RTT1RMYXRlVW5pdHMsIA0KICAgICAgICAgUFBBVW5pdHMsDQogICAgICAgICBQUEFTT1RMYXRlVW5pdHMsDQogICAgICAgICBQUEFTT1Q1ZGF5c0xhdGVVbml0cywNCiAgICAgICAgIFdUUFBBU09UTGF0ZVVuaXRzKSAlPiUgDQogIGFycmFuZ2UoU2hpcENhbmNlbE1vbnRoLCBDYXRlZ29yeSkNCiMgQ3JlYXRlIE1vbnRobHkgUHJlZmVycmVkIFZlbmRvciAtIE5ldyBPVFMgLS0tLQ0KTW9udGhseV9QcmVmZXJyZWRfVmVuZG9yX05ld19PVFMgPC0gaW5uZXJfam9pbihPVFNfTWFzdGVyLCBQcmVmZXJyZWRfVmVuZG9yX25ldywgYnkgPSBjKCJDYXRlZ29yeSI9ICJOZXcgQ2F0ZWdvcnkiLCAiUGFyZW50X1ZlbmRvciI9IlZlbmRvciBOYW1lIikpICU+JSANCiAgZmlsdGVyKFdlZWsgPD0gRU9XKSAlPiUNCiAgZ3JvdXBfYnkoQ2F0ZWdvcnksIFBhcmVudF9WZW5kb3IsICBNb250aF9OdW1iZXIgKSAlPiUgDQogIHN1bW1hcmlzZSgiT1RTVW5pdHMiID0gZmxvb3Ioc3VtKFVuaXRzKSksDQogICAgICAgICAgICAiT1RTT25UaW1lVW5pdHMiID0gZmxvb3Ioc3VtKFVuaXRzW0xhdGVuZXNzPT0iT25UaW1lIl0pKSwNCiAgICAgICAgICAgICJPVFNMYXRlVW5pdHMiPSBmbG9vcihzdW0oVW5pdHNbTGF0ZW5lc3M9PSJMYXRlIl0pKSwNCiAgICAgICAgICAgICJPVFNMYXRlNWRheXNVbml0cyIgPSBmbG9vcihzdW0oVW5pdHNbTGF0ZW5lc3M9PSJMYXRlIiAmIERheXNfTGF0ZSA+IDVdKSksIA0KICAgICAgICAgICAgIldUT1RTTGF0ZVVuaXRzIiA9IGZsb29yKHN1bShVbml0c1tMYXRlbmVzcz09IkxhdGUiXSpEYXlzX0xhdGVbTGF0ZW5lc3M9PSJMYXRlIiAmIERheXNfTGF0ZSA+PTFdKSksDQogICAgICAgICAgICAiUFBBT1RTTGF0ZVVuaXRzIiA9IGZsb29yKHN1bShVbml0c1tTSFBfTU9ERV9DQVRHX05NID09ICJQcmVwYWlkQWlyIiAmIExhdGVuZXNzPT0iTGF0ZSJdKSkpICU+JSAgDQogIHNlbGVjdChDYXRlZ29yeSwgDQogICAgICAgICBQYXJlbnRfVmVuZG9yLA0KICAgICAgICAgTW9udGhfTnVtYmVyLA0KICAgICAgICAgT1RTVW5pdHMsIA0KICAgICAgICAgT1RTT25UaW1lVW5pdHMsIA0KICAgICAgICAgT1RTTGF0ZVVuaXRzLCANCiAgICAgICAgIE9UU0xhdGU1ZGF5c1VuaXRzLCANCiAgICAgICAgIFdUT1RTTGF0ZVVuaXRzLCANCiAgICAgICAgIFBQQU9UU0xhdGVVbml0cykgJT4lIA0KICBhcnJhbmdlKE1vbnRoX051bWJlciwgQ2F0ZWdvcnkpDQojIFZpZXcoTW9udGhseV9QcmVmZXJyZWRfVmVuZG9yX05ld19PVFMpDQoNCg0KIyBDcmVhdGUgTW9udGhseSBCcmFuZCBhbmQgQ2F0ZWdvcnkgQ29tYmluZSBUYWJsZSAtLS0tDQpNb250aGx5X0JyYW5kX0NhdGVnb3J5X0NvbWJpbmUgPC0gbGVmdF9qb2luKE1vbnRobHlfQnJhbmRfQ2F0ZWdvcnlfU09ULCBNb250aGx5X0JyYW5kX0NhdGVnb3J5X09UUywgYnk9IGMoIlNoaXBDYW5jZWxNb250aCI9Ik1vbnRoX051bWJlciIsICJSZXBvcnRpbmdCcmFuZCI9IlJlcG9ydGluZ0JyYW5kIiwgIkNhdGVnb3J5Ij0iQ2F0ZWdvcnkiKSkNCk1vbnRobHlfQnJhbmRfQ2F0ZWdvcnlfQ29tYmluZSA8LSBNb250aGx5X0JyYW5kX0NhdGVnb3J5X0NvbWJpbmVbYygxOjgsIDEzOjE3LDk6MTAsMTgsMTE6MTIpXQ0KDQojIENyZWF0ZSBNb250aGx5IFNPVCBCcmFuZCBDb21iaW5lIFRhYmxlIC0tLS0NCk1vbnRobHlfQnJhbmRfQ29tYmluZSA8LSBsZWZ0X2pvaW4oTW9udGhseV9CcmFuZF9TT1QsIE1vbnRobHlfQnJhbmRfT1RTLCBieT0gYygiU2hpcENhbmNlbE1vbnRoIj0iTW9udGhfTnVtYmVyIiwgIlJlcG9ydGluZ0JyYW5kIj0iUmVwb3J0aW5nQnJhbmQiKSkNCk1vbnRobHlfQnJhbmRfQ29tYmluZSA8LSBNb250aGx5X0JyYW5kX0NvbWJpbmVbYygxOjcsIDEyOjE2LCA4OjksIDE3LCAxMDoxMSldDQojIFZpZXcoTW9udGhseV9CcmFuZF9Db21iaW5lKQ0KDQojIENyZWF0ZSBNb250aGx5IFNPVCBDYXRlZ29yeSBDb21iaW5lIFRhYmxlIC0tLS0NCk1vbnRobHlfQ2F0ZWdvcnlfQ29tYmluZSA8LSBsZWZ0X2pvaW4oTW9udGhseV9DYXRlZ29yeV9TT1QsIE1vbnRobHlfQ2F0ZWdvcnlfT1RTLCBieT0gYygiU2hpcENhbmNlbE1vbnRoIj0iTW9udGhfTnVtYmVyIiwgIkNhdGVnb3J5Ij0iQ2F0ZWdvcnkiKSkNCk1vbnRobHlfQ2F0ZWdvcnlfQ29tYmluZSA8LSBNb250aGx5X0NhdGVnb3J5X0NvbWJpbmVbYygxOjcsIDEyOjE2LCA4OjksIDE3LCAxMDoxMSldDQojIFZpZXcoTW9udGhseV9DYXRlZ29yeV9Db21iaW5lKQ0KDQojIENyZWF0ZSBNb250aGx5IFNPVCBHYXAgSW5jIENvbWJpbmUgVGFibGUgLS0tLQ0KTW9udGhseV9HYXBJbmNfQ29tYmluZSA8LSBsZWZ0X2pvaW4oTW9udGhseV9HYXBJbmNfU09ULCBNb250aGx5X0dhcEluY19PVFMsIGJ5PSBjKCJTaGlwQ2FuY2VsTW9udGgiPSJNb250aF9OdW1iZXIiKSkNCk1vbnRobHlfR2FwSW5jX0NvbWJpbmUgPC0gTW9udGhseV9HYXBJbmNfQ29tYmluZVtjKDE6NiwgMTE6MTUsNzo4LDE2LDk6MTApXQ0KIyBWaWV3KE1vbnRobHlfR2FwSW5jX0NvbWJpbmUpDQojIENyZWF0ZSBQcmVmZXJyZWQgVmVuZG9yIENvbWJpbmUgVGFibGUgLS0tLQ0KUHJlZmVycmVkX1ZlbmRvcl9OZXdfQ29tYmluZSA8LSBsZWZ0X2pvaW4oTW9udGhseV9QcmVmZXJyZWRfVmVuZG9yX25ldywgTW9udGhseV9QcmVmZXJyZWRfVmVuZG9yX05ld19PVFMsIGJ5ID0gYygiQ2F0ZWdvcnkiPSJDYXRlZ29yeSIsICJQYXJlbnRfVmVuZG9yIj0iUGFyZW50X1ZlbmRvciIsICJTaGlwQ2FuY2VsTW9udGgiID0gIk1vbnRoX051bWJlciIpKQ0KUHJlZmVycmVkX1ZlbmRvcl9OZXdfQ29tYmluZSA8LVByZWZlcnJlZF9WZW5kb3JfTmV3X0NvbWJpbmVbYygxOjgsIDEzOjE3LCA5OjEwLCAxOCwgMTE6MTIpXQ0KDQojIENyZWF0ZSBNb250aGx5IC0gYnlEQw0KTW9udGhseV9ieV9EQyA8LSBPVFNfTWFzdGVyICU+JSANCiAgZmlsdGVyKE9UU19NYXN0ZXIkV2VlayA8PSBFT1cpICU+JQ0KICBncm91cF9ieShGaXNjYWxfTW9udGgsIE1vbnRoX051bWJlciwgRENDYW1wdXMsIERDX05BTUUsIERlc3RDdHJ5Q0QpICU+JSANCiAgc3VtbWFyaXNlKCJUb3RhbCBVbml0cyIgPSBmbG9vcihzdW0oVW5pdHMpKSwNCiAgICAgICAgICAgICJPblRpbWVVbml0cyIgPSBmbG9vcihzdW0oVW5pdHNbTGF0ZW5lc3M9PSJPblRpbWUiXSkpLA0KICAgICAgICAgICAgIk9UUyUiID0gc3VtKFVuaXRzW0xhdGVuZXNzPT0iT25UaW1lIl0pL3N1bShVbml0cyksDQogICAgICAgICAgICAiT1RTTGF0ZTVkYXlzVW5pdHMiID0gZmxvb3Ioc3VtKFVuaXRzW0xhdGVuZXNzPT0iTGF0ZSIgJiBEYXlzX0xhdGUgPiA1XSkpLA0KICAgICAgICAgICAgIldUT1RTTGF0ZVVuaXRzIiA9IGZsb29yKHN1bShVbml0c1tMYXRlbmVzcz09IkxhdGUiXSpEYXlzX0xhdGVbTGF0ZW5lc3M9PSJMYXRlIiAmIERheXNfTGF0ZSA+PTFdKSksDQogICAgICAgICAgICAiTGF0ZVVuaXRzIj0gZmxvb3Ioc3VtKFVuaXRzW0xhdGVuZXNzPT0iTGF0ZSJdKSkpICU+JSANCiAgc2VsZWN0KEZpc2NhbF9Nb250aCwgDQogICAgICAgICBNb250aF9OdW1iZXIsIA0KICAgICAgICAgYE9uVGltZVVuaXRzYCwgDQogICAgICAgICBgVG90YWwgVW5pdHNgLCANCiAgICAgICAgIERDQ2FtcHVzLCANCiAgICAgICAgIERDX05BTUUsIA0KICAgICAgICAgRGVzdEN0cnlDRCwgDQogICAgICAgICBgT1RTJWAsIA0KICAgICAgICAgYE9UU0xhdGU1ZGF5c1VuaXRzYCwNCiAgICAgICAgIGBXVE9UU0xhdGVVbml0c2AsIA0KICAgICAgICAgYExhdGVVbml0c2ApDQojIENyZWF0ZSBUb3AgMjAgQ291bnRyaWVzIFNPVCAtLS0tDQpNb250aGx5X1RvcF8yMF9TT1QgPC0gaW5uZXJfam9pbihTT1RfTWFzdGVyLCBUb3BfMjBfQ291bnRyaWVzLCBieSA9IGMoIkNvdW50cnlPZk9yaWdpbiI9ICJDb3VudHJ5T2ZPcmlnaW4iKSkNCk1vbnRobHlfVG9wXzIwX1NPVCA8LSBNb250aGx5X1RvcF8yMF9TT1QgJT4lDQogIGZpbHRlcihTaGlwQ2FuY2VsV2VlayA8PSBFT1cpICU+JQ0KICBncm91cF9ieShTaGlwQ2FuY2VsTW9udGgpICU+JSANCiAgc3VtbWFyaXNlKCJTT1RVbml0cyIgPSBmbG9vcihzdW0oVW5pdHMpKSwNCiAgICAgICAgICAgICJTT1RPblRpbWVVbml0cyIgPSBmbG9vcihzdW0oVW5pdHNbTGF0ZW5lc3M9PSJPblRpbWUiXSkpLA0KICAgICAgICAgICAgIlNPVExhdGVVbml0cyI9IGZsb29yKHN1bShVbml0c1tMYXRlbmVzcz09IkxhdGUiXSkpLA0KICAgICAgICAgICAgIlNPVExhdGU1ZGF5c1VuaXRzIiA9IGZsb29yKHN1bShVbml0c1tMYXRlbmVzcz09IkxhdGUiICYgREFZU19MQVRFID4gNV0pKSwgDQogICAgICAgICAgICAiV1RTT1RMYXRlVW5pdHMiID0gZmxvb3Ioc3VtKFVuaXRzW0xhdGVuZXNzPT0iTGF0ZSJdKkRBWVNfTEFURVtMYXRlbmVzcz09IkxhdGUiICYgREFZU19MQVRFID49MV0pKSwNCiAgICAgICAgICAgICJQUEFVbml0cyIgPSBmbG9vcihzdW0oVW5pdHNbU0hQX01PREVfQ0FUR19OTSA9PSAiUHJlcGFpZEFpciJdKSksDQogICAgICAgICAgICAiUFBBU09UTGF0ZVVuaXRzIiA9IGZsb29yKHN1bShVbml0c1tTSFBfTU9ERV9DQVRHX05NID09ICJQcmVwYWlkQWlyIiAmIExhdGVuZXNzPT0iTGF0ZSJdKSksIA0KICAgICAgICAgICAgIlBQQVNPVDVkYXlzTGF0ZVVuaXRzIiA9IGZsb29yKHN1bShVbml0c1tTSFBfTU9ERV9DQVRHX05NID09ICJQcmVwYWlkQWlyIiAmIExhdGVuZXNzPT0iTGF0ZSIgJiBEQVlTX0xBVEU+NV0pKSwNCiAgICAgICAgICAgICJXVFBQQVNPVExhdGVVbml0cyIgPSBmbG9vcihzdW0oVW5pdHNbU0hQX01PREVfQ0FUR19OTSA9PSAiUHJlcGFpZEFpciIgJiBMYXRlbmVzcz09IkxhdGUiXSpEQVlTX0xBVEVbU0hQX01PREVfQ0FUR19OTSA9PSAiUHJlcGFpZEFpciIgJiBMYXRlbmVzcz09IkxhdGUiICYgREFZU19MQVRFID49MV0pKSkgJT4lICANCiAgc2VsZWN0KFNoaXBDYW5jZWxNb250aCwgDQogICAgICAgICBTT1RVbml0cywgDQogICAgICAgICBTT1RPblRpbWVVbml0cywgDQogICAgICAgICBTT1RMYXRlVW5pdHMsIA0KICAgICAgICAgU09UTGF0ZTVkYXlzVW5pdHMsIA0KICAgICAgICAgV1RTT1RMYXRlVW5pdHMsIA0KICAgICAgICAgUFBBVW5pdHMsDQogICAgICAgICBQUEFTT1RMYXRlVW5pdHMsDQogICAgICAgICBQUEFTT1Q1ZGF5c0xhdGVVbml0cywNCiAgICAgICAgIFdUUFBBU09UTGF0ZVVuaXRzKQ0KIyBWaWV3KE1vbnRobHlfVG9wXzIwX1NPVCkgDQoNCiMgQ3JlYXRlIE1vbnRobHkgVG9wIDIwIE9UUyBUYWJsZSAtLS0tDQpNb250aGx5X1RPUF8yMF9PVFMgPC0gaW5uZXJfam9pbihPVFNfTWFzdGVyLCBUb3BfMjBfQ291bnRyaWVzLCBieSA9IGMoIk9SSUdJTl9DT1VOVFJZX0NPREUiPSJDb3VudHJ5T2ZPcmlnaW4iKSkNCk1vbnRobHlfVE9QXzIwX09UUyA8LSBNb250aGx5X1RPUF8yMF9PVFMgJT4lDQogIGZpbHRlcihXZWVrIDw9IEVPVykgJT4lDQogIGdyb3VwX2J5KE1vbnRoX051bWJlcikgJT4lIA0KICBzdW1tYXJpc2UoIk9UU1VuaXRzIiA9IHN1bShVbml0cyksDQogICAgICAgICAgICAiT1RTT25UaW1lVW5pdHMiID0gZmxvb3Ioc3VtKFVuaXRzW0xhdGVuZXNzPT0iT25UaW1lIl0pKSwNCiAgICAgICAgICAgICJPVFNMYXRlVW5pdHMiPSBmbG9vcihzdW0oVW5pdHNbTGF0ZW5lc3M9PSJMYXRlIl0pKSwNCiAgICAgICAgICAgICJPVFNMYXRlNWRheXNVbml0cyIgPSBmbG9vcihzdW0oVW5pdHNbTGF0ZW5lc3M9PSJMYXRlIiAmIERheXNfTGF0ZSA+IDVdKSksIA0KICAgICAgICAgICAgIldUT1RTTGF0ZVVuaXRzIiA9IGZsb29yKHN1bShVbml0c1tMYXRlbmVzcz09IkxhdGUiXSpEYXlzX0xhdGVbTGF0ZW5lc3M9PSJMYXRlIiAmIERheXNfTGF0ZSA+PTFdKSksDQogICAgICAgICAgICAiUFBBT1RTTGF0ZVVuaXRzIiA9IGZsb29yKHN1bShVbml0c1tTSFBfTU9ERV9DQVRHX05NID09ICJQcmVwYWlkQWlyIiAmIExhdGVuZXNzPT0iTGF0ZSJdKSkpICU+JSAgDQogIHNlbGVjdChNb250aF9OdW1iZXIsIA0KICAgICAgICAgT1RTVW5pdHMsIA0KICAgICAgICAgT1RTT25UaW1lVW5pdHMsIA0KICAgICAgICAgT1RTTGF0ZVVuaXRzLCANCiAgICAgICAgIE9UU0xhdGU1ZGF5c1VuaXRzLCANCiAgICAgICAgIFdUT1RTTGF0ZVVuaXRzLCANCiAgICAgICAgIFBQQU9UU0xhdGVVbml0cykNCiMgIFZpZXcoTW9udGhseV9UT1BfMjBfT1RTKQ0KIyBDcmVhdGUgTW9udGhseSBUb3AgMjAgQ29tYmluZSB0YWJsZSAtLS0tDQpNb250aGx5X1RvcF8yMF9Db21iaW5lIDwtIGlubmVyX2pvaW4oTW9udGhseV9Ub3BfMjBfU09ULCBNb250aGx5X1RPUF8yMF9PVFMsIGJ5PSBjKCJTaGlwQ2FuY2VsTW9udGgiPSJNb250aF9OdW1iZXIiKSkNCk1vbnRobHlfVG9wXzIwX0NvbWJpbmUgPC0gTW9udGhseV9Ub3BfMjBfQ29tYmluZVtjKDE6NiwgMTE6MTUsNzo4LDE2LDk6MTApXQ0KICANCiMgQ3JlYXRlIE1vbnRobHkgVG9wIDUwIFZlbmRvcnMgU09UIFRhYmxlIC0tLS0NCk1vbnRobHlfVG9wXzUwX1ZlbmRvcnNfU09UIDwtIGlubmVyX2pvaW4oU09UX01hc3RlciwgVG9wXzUwX1ZlbmRvcnMsIGJ5ID0gYygiUGFyZW50X1ZlbmRvciI9ICJQYXJlbnRfVmVuZG9yIikpDQpNb250aGx5X1RvcF81MF9WZW5kb3JzX1NPVCA8LSBNb250aGx5X1RvcF81MF9WZW5kb3JzX1NPVCAlPiUNCiAgZmlsdGVyKFNoaXBDYW5jZWxXZWVrIDw9IEVPVykgJT4lDQogIGdyb3VwX2J5KFNoaXBDYW5jZWxNb250aCkgJT4lIA0KICBzdW1tYXJpc2UoIlNPVFVuaXRzIiA9IGZsb29yKHN1bShVbml0cykpLA0KICAgICAgICAgICAgIlNPVE9uVGltZVVuaXRzIiA9IGZsb29yKHN1bShVbml0c1tMYXRlbmVzcz09Ik9uVGltZSJdKSksDQogICAgICAgICAgICAiU09UTGF0ZVVuaXRzIj0gZmxvb3Ioc3VtKFVuaXRzW0xhdGVuZXNzPT0iTGF0ZSJdKSksDQogICAgICAgICAgICAiU09UTGF0ZTVkYXlzVW5pdHMiID0gZmxvb3Ioc3VtKFVuaXRzW0xhdGVuZXNzPT0iTGF0ZSIgJiBEQVlTX0xBVEUgPiA1XSkpLCANCiAgICAgICAgICAgICJXVFNPVExhdGVVbml0cyIgPSBmbG9vcihzdW0oVW5pdHNbTGF0ZW5lc3M9PSJMYXRlIl0qREFZU19MQVRFW0xhdGVuZXNzPT0iTGF0ZSIgJiBEQVlTX0xBVEUgPj0xXSkpLA0KICAgICAgICAgICAgIlBQQVVuaXRzIiA9IGZsb29yKHN1bShVbml0c1tTSFBfTU9ERV9DQVRHX05NID09ICJQcmVwYWlkQWlyIl0pKSwNCiAgICAgICAgICAgICJQUEFTT1RMYXRlVW5pdHMiID0gZmxvb3Ioc3VtKFVuaXRzW1NIUF9NT0RFX0NBVEdfTk0gPT0gIlByZXBhaWRBaXIiICYgTGF0ZW5lc3M9PSJMYXRlIl0pKSwgDQogICAgICAgICAgICAiUFBBU09UNWRheXNMYXRlVW5pdHMiID0gZmxvb3Ioc3VtKFVuaXRzW1NIUF9NT0RFX0NBVEdfTk0gPT0gIlByZXBhaWRBaXIiICYgTGF0ZW5lc3M9PSJMYXRlIiAmIERBWVNfTEFURT41XSkpLA0KICAgICAgICAgICAgIldUUFBBU09UTGF0ZVVuaXRzIiA9IGZsb29yKHN1bShVbml0c1tTSFBfTU9ERV9DQVRHX05NID09ICJQcmVwYWlkQWlyIiAmIExhdGVuZXNzPT0iTGF0ZSJdKkRBWVNfTEFURVtTSFBfTU9ERV9DQVRHX05NID09ICJQcmVwYWlkQWlyIiAmIExhdGVuZXNzPT0iTGF0ZSIgJiBEQVlTX0xBVEUgPj0xXSkpKSAlPiUgIA0KICBzZWxlY3QoU2hpcENhbmNlbE1vbnRoLCANCiAgICAgICAgIFNPVFVuaXRzLCANCiAgICAgICAgIFNPVE9uVGltZVVuaXRzLCANCiAgICAgICAgIFNPVExhdGVVbml0cywgDQogICAgICAgICBTT1RMYXRlNWRheXNVbml0cywgDQogICAgICAgICBXVFNPVExhdGVVbml0cywgDQogICAgICAgICBQUEFVbml0cywNCiAgICAgICAgIFBQQVNPVExhdGVVbml0cywNCiAgICAgICAgIFBQQVNPVDVkYXlzTGF0ZVVuaXRzLA0KICAgICAgICAgV1RQUEFTT1RMYXRlVW5pdHMpDQogIyBWaWV3KE1vbnRobHlfVG9wXzUwX1ZlbmRvcnNfU09UKSANCiMgQ3JlYXRlIE1vbnRobHkgVG9wIDUwIFZlbmRvcnMgT1RTIFRhYmxlIC0tLS0NCk1vbnRobHlfVG9wXzUwX1ZlbmRvcnNfT1RTIDwtIGlubmVyX2pvaW4oT1RTX01hc3RlciwgVG9wXzUwX1ZlbmRvcnMsIGJ5ID0gYygiUGFyZW50X1ZlbmRvciI9ICJQYXJlbnRfVmVuZG9yIikpDQpNb250aGx5X1RvcF81MF9WZW5kb3JzX09UUyA8LSBNb250aGx5X1RvcF81MF9WZW5kb3JzX09UUyAlPiUNCiAgZmlsdGVyKFdlZWsgPD0gRU9XKSAlPiUNCiAgZ3JvdXBfYnkoTW9udGhfTnVtYmVyKSAlPiUgDQogIHN1bW1hcmlzZSgiT1RTVW5pdHMiID0gc3VtKFVuaXRzKSwNCiAgICAgICAgICAgICJPVFNPblRpbWVVbml0cyIgPSBmbG9vcihzdW0oVW5pdHNbTGF0ZW5lc3M9PSJPblRpbWUiXSkpLA0KICAgICAgICAgICAgIk9UU0xhdGVVbml0cyI9IGZsb29yKHN1bShVbml0c1tMYXRlbmVzcz09IkxhdGUiXSkpLA0KICAgICAgICAgICAgIk9UU0xhdGU1ZGF5c1VuaXRzIiA9IGZsb29yKHN1bShVbml0c1tMYXRlbmVzcz09IkxhdGUiICYgRGF5c19MYXRlID4gNV0pKSwgDQogICAgICAgICAgICAiV1RPVFNMYXRlVW5pdHMiID0gZmxvb3Ioc3VtKFVuaXRzW0xhdGVuZXNzPT0iTGF0ZSJdKkRheXNfTGF0ZVtMYXRlbmVzcz09IkxhdGUiICYgRGF5c19MYXRlID49MV0pKSwNCiAgICAgICAgICAgICJQUEFPVFNMYXRlVW5pdHMiID0gZmxvb3Ioc3VtKFVuaXRzW1NIUF9NT0RFX0NBVEdfTk0gPT0gIlByZXBhaWRBaXIiICYgTGF0ZW5lc3M9PSJMYXRlIl0pKSkgJT4lICANCiAgc2VsZWN0KE1vbnRoX051bWJlciwgDQogICAgICAgICBPVFNVbml0cywgDQogICAgICAgICBPVFNPblRpbWVVbml0cywgDQogICAgICAgICBPVFNMYXRlVW5pdHMsIA0KICAgICAgICAgT1RTTGF0ZTVkYXlzVW5pdHMsIA0KICAgICAgICAgV1RPVFNMYXRlVW5pdHMsIA0KICAgICAgICAgUFBBT1RTTGF0ZVVuaXRzKQ0KICMgVmlldyhNb250aGx5X0dhcEluY19PVFMpDQoNCg0KIyBDcmVhdGUgTW9udGhseSBTT1QgVG9wIDUwIFZlbmRvcnMgQ29tYmluZSBUYWJsZSAtLS0tDQpNb250aGx5X1RvcF81MF9WZW5kb3JzX0NvbWJpbmUgPC0gbGVmdF9qb2luKE1vbnRobHlfVG9wXzUwX1ZlbmRvcnNfU09ULCBNb250aGx5X1RvcF81MF9WZW5kb3JzX09UUywgYnk9IGMoIlNoaXBDYW5jZWxNb250aCI9Ik1vbnRoX051bWJlciIpKQ0KTW9udGhseV9Ub3BfNTBfVmVuZG9yc19Db21iaW5lIDwtIE1vbnRobHlfVG9wXzUwX1ZlbmRvcnNfQ29tYmluZVtjKDE6NiwgMTE6MTUsNzo4LDE2LDk6MTApXQ0KIyBWaWV3KE1vbnRobHlfVG9wXzUwX19WZW5kb3JzX0NvbWJpbmUpDQojIENyZWF0ZSBPVFN2c1NPVCB0YWJsZSAtLS0tDQogT1RTX3ZzIDwtIE9UU19NYXN0ZXIgJT4lIA0KICAgc2VsZWN0KE5VTUJFUl9TRVEsIE1vbnRoX051bWJlciwgTGF0ZW5lc3MsIFVuaXRzKSAlPiUNCiAgIGZpbHRlcihMYXRlbmVzcyE9ICJVbmRldGVybWluZWQiKSAlPiUgDQogICByZW5hbWUoIlN0b2NrZWRPblRpbWUiID0gTGF0ZW5lc3MpICU+JQ0KICAgZ3JvdXBfYnkoTW9udGhfTnVtYmVyLCBTdG9ja2VkT25UaW1lKSAlPiUgDQogICBkcm9wbGV2ZWxzKCkNCiANCiBTT1RfdnMgPC0gU09UX01hc3RlciAlPiUgDQogICBzZWxlY3QoTlVNQkVSX1NFUSwgU2hpcENhbmNlbE1vbnRoLCBMYXRlbmVzcykgJT4lDQogICBmaWx0ZXIoTGF0ZW5lc3MhPSJVbm1lYXN1cmVkIikgJT4lIA0KICAgcmVuYW1lKCJTaGlwcGVkT25UaW1lIiA9IExhdGVuZXNzKSAlPiUNCiAgIGdyb3VwX2J5KFNoaXBDYW5jZWxNb250aCwgU2hpcHBlZE9uVGltZSkgJT4lIA0KICAgZHJvcGxldmVscygpDQogDQogT1RTdnNTT1QgPC0gaW5uZXJfam9pbihPVFNfdnMsIFNPVF92cywgYnkgPSBjKCJOVU1CRVJfU0VRIj0gIk5VTUJFUl9TRVEiKSkgJT4lDQogICBncm91cF9ieShNb250aF9OdW1iZXIsIFN0b2NrZWRPblRpbWUsIFNoaXBwZWRPblRpbWUpICU+JSANCiAgIHN1bW1hcmlzZSgiU3VtT2ZVbml0cyIgPSBmbG9vcihzdW0oVW5pdHMpKSkNCiANCiMgQ3JlYXRlIE1vbnRobHkgQnJhbmQgVG9wIDEwIERlbGF5IENvbWJpbmUgLS0tLQ0KQnJhbmRfVG9wX1Rlbl9EZWxheSA8LSAgU09UX01hc3RlciAlPiUgDQogICBmaWx0ZXIoU2hpcENhbmNlbFdlZWsgPD0gRU9XKSAlPiUNCiAgIGdyb3VwX2J5KFJlcG9ydGluZ0JyYW5kLCBTaGlwQ2FuY2VsTW9udGgsIFBhcmVudF9WZW5kb3IpICU+JSANCiAgIHN1bW1hcmlzZSgiU09UVW5pdHMiID0gZmxvb3Ioc3VtKFVuaXRzKSksDQogICAgICAgICAgICAgIkFkanVzdGVkU09UVW5pdHMiPSBmbG9vcihzdW0oVW5pdHNbTGF0ZW5lc3M9PSJPblRpbWUiXSkgKyBzdW0oVW5pdHNbTGF0ZW5lc3M9PSJMYXRlIl0pKSwNCiAgICAgICAgICAgICAiU09UT25UaW1lVW5pdHMiID0gZmxvb3Ioc3VtKFVuaXRzW0xhdGVuZXNzPT0iT25UaW1lIl0pKSwNCiAgICAgICAgICAgICAiU09UTGF0ZVVuaXRzIj0gZmxvb3Ioc3VtKFVuaXRzW0xhdGVuZXNzPT0iTGF0ZSJdKSksDQogICAgICAgICAgICAgIlNPVExhdGU1ZGF5c1VuaXRzIiA9IGZsb29yKHN1bShVbml0c1tMYXRlbmVzcz09IkxhdGUiICYgREFZU19MQVRFID4gNV0pKSwgDQogICAgICAgICAgICAgIldUU09UTGF0ZVVuaXRzIiA9IGZsb29yKHN1bShVbml0c1tMYXRlbmVzcz09IkxhdGUiXSpEQVlTX0xBVEVbTGF0ZW5lc3M9PSJMYXRlIiAmIERBWVNfTEFURSA+PTFdKSksDQogICAgICAgICAgICAgIlBQQVVuaXRzIiA9IGZsb29yKHN1bShVbml0c1tTSFBfTU9ERV9DQVRHX05NID09ICJQcmVwYWlkQWlyIl0pKSwNCiAgICAgICAgICAgICAiUFBBU09UTGF0ZVVuaXRzIiA9IGZsb29yKHN1bShVbml0c1tTSFBfTU9ERV9DQVRHX05NID09ICJQcmVwYWlkQWlyIiAmIExhdGVuZXNzPT0iTGF0ZSJdKSksIA0KICAgICAgICAgICAgICJQUEFTT1Q1ZGF5c0xhdGVVbml0cyIgPSBmbG9vcihzdW0oVW5pdHNbU0hQX01PREVfQ0FUR19OTSA9PSAiUHJlcGFpZEFpciIgJiBMYXRlbmVzcz09IkxhdGUiICYgREFZU19MQVRFPjVdKSksDQogICAgICAgICAgICAgIldUUFBBU09UTGF0ZVVuaXRzIiA9IGZsb29yKHN1bShVbml0c1tTSFBfTU9ERV9DQVRHX05NID09ICJQcmVwYWlkQWlyIiAmIExhdGVuZXNzPT0iTGF0ZSJdKkRBWVNfTEFURVtTSFBfTU9ERV9DQVRHX05NID09ICJQcmVwYWlkQWlyIiAmIExhdGVuZXNzPT0iTGF0ZSIgJiBEQVlTX0xBVEUgPj0xXSkpKSAlPiUgIA0KICAgc2VsZWN0KA0KICAgICAgICAgIFJlcG9ydGluZ0JyYW5kLA0KICAgICAgICAgIFNoaXBDYW5jZWxNb250aCwNCiAgICAgICAgICBQYXJlbnRfVmVuZG9yLA0KICAgICAgICAgIFNPVFVuaXRzLA0KICAgICAgICAgIEFkanVzdGVkU09UVW5pdHMsDQogICAgICAgICAgU09UT25UaW1lVW5pdHMsIA0KICAgICAgICAgIFNPVExhdGVVbml0cywgDQogICAgICAgICAgU09UTGF0ZTVkYXlzVW5pdHMsIA0KICAgICAgICAgIFdUU09UTGF0ZVVuaXRzKSAlPiUgDQogICB0b3BfbigxMCwgU09UTGF0ZVVuaXRzKSAlPiUgDQogICBhcnJhbmdlKFJlcG9ydGluZ0JyYW5kLFNoaXBDYW5jZWxNb250aCwgZGVzYyhTT1RMYXRlVW5pdHMpKQ0KICAgDQojIENyZWF0ZSBNb250aGx5IENhdGVnb3J5IFRvcCAxMCBEZWxheSBDb21iaW5lIC0tLS0NCkNhdGVnb3J5X1RvcF9UZW5fRGVsYXkgPC0gIFNPVF9NYXN0ZXIgJT4lIA0KICAgZmlsdGVyKFNoaXBDYW5jZWxXZWVrIDw9IEVPVykgJT4lDQogICBncm91cF9ieShDYXRlZ29yeSwgU2hpcENhbmNlbE1vbnRoLCBQYXJlbnRfVmVuZG9yKSAlPiUgDQogICBzdW1tYXJpc2UoIlNPVFVuaXRzIiA9IGZsb29yKHN1bShVbml0cykpLA0KICAgICAgICAgICAgICJBZGp1c3RlZFNPVFVuaXRzIj0gZmxvb3Ioc3VtKFVuaXRzW0xhdGVuZXNzPT0iT25UaW1lIl0pICsgc3VtKFVuaXRzW0xhdGVuZXNzPT0iTGF0ZSJdKSksDQogICAgICAgICAgICAgIlNPVE9uVGltZVVuaXRzIiA9IGZsb29yKHN1bShVbml0c1tMYXRlbmVzcz09Ik9uVGltZSJdKSksDQogICAgICAgICAgICAgIlNPVExhdGVVbml0cyI9IGZsb29yKHN1bShVbml0c1tMYXRlbmVzcz09IkxhdGUiXSkpLA0KICAgICAgICAgICAgICJTT1RMYXRlNWRheXNVbml0cyIgPSBmbG9vcihzdW0oVW5pdHNbTGF0ZW5lc3M9PSJMYXRlIiAmIERBWVNfTEFURSA+IDVdKSksIA0KICAgICAgICAgICAgICJXVFNPVExhdGVVbml0cyIgPSBmbG9vcihzdW0oVW5pdHNbTGF0ZW5lc3M9PSJMYXRlIl0qREFZU19MQVRFW0xhdGVuZXNzPT0iTGF0ZSIgJiBEQVlTX0xBVEUgPj0xXSkpLA0KICAgICAgICAgICAgICJQUEFVbml0cyIgPSBmbG9vcihzdW0oVW5pdHNbU0hQX01PREVfQ0FUR19OTSA9PSAiUHJlcGFpZEFpciJdKSksDQogICAgICAgICAgICAgIlBQQVNPVExhdGVVbml0cyIgPSBmbG9vcihzdW0oVW5pdHNbU0hQX01PREVfQ0FUR19OTSA9PSAiUHJlcGFpZEFpciIgJiBMYXRlbmVzcz09IkxhdGUiXSkpLCANCiAgICAgICAgICAgICAiUFBBU09UNWRheXNMYXRlVW5pdHMiID0gZmxvb3Ioc3VtKFVuaXRzW1NIUF9NT0RFX0NBVEdfTk0gPT0gIlByZXBhaWRBaXIiICYgTGF0ZW5lc3M9PSJMYXRlIiAmIERBWVNfTEFURT41XSkpLA0KICAgICAgICAgICAgICJXVFBQQVNPVExhdGVVbml0cyIgPSBmbG9vcihzdW0oVW5pdHNbU0hQX01PREVfQ0FUR19OTSA9PSAiUHJlcGFpZEFpciIgJiBMYXRlbmVzcz09IkxhdGUiXSpEQVlTX0xBVEVbU0hQX01PREVfQ0FUR19OTSA9PSAiUHJlcGFpZEFpciIgJiBMYXRlbmVzcz09IkxhdGUiICYgREFZU19MQVRFID49MV0pKSkgJT4lICANCiAgIHNlbGVjdCgNCiAgICAgICAgICBDYXRlZ29yeSwNCiAgICAgICAgICBTaGlwQ2FuY2VsTW9udGgsDQogICAgICAgICAgUGFyZW50X1ZlbmRvciwNCiAgICAgICAgICBTT1RVbml0cywNCiAgICAgICAgICBBZGp1c3RlZFNPVFVuaXRzLA0KICAgICAgICAgIFNPVE9uVGltZVVuaXRzLCANCiAgICAgICAgICBTT1RMYXRlVW5pdHMsIA0KICAgICAgICAgIFNPVExhdGU1ZGF5c1VuaXRzLCANCiAgICAgICAgICBXVFNPVExhdGVVbml0cykgJT4lIA0KICAgdG9wX24oMTAsIFNPVExhdGVVbml0cykgJT4lIA0KICAgYXJyYW5nZShDYXRlZ29yeSwgU2hpcENhbmNlbE1vbnRoLCBkZXNjKFNPVExhdGVVbml0cykpDQogICANCiMgV3JpdGUgdGFibGVzIC0tLS0NCndyaXRlX2NzdihNb250aGx5X0JyYW5kX0NhdGVnb3J5X0NvbWJpbmUsIA0KICAgICAgICAgIHBhdGggPSBwYXN0ZShTT1RfT1RTX2RpcmVjdG9yeSwgIA0KICAgICAgICAgICAgICAgICAgICAgICBwYXN0ZSgnTW9udGhseV9CcmFuZF9DYXRlZ29yeV9Db21iaW5lX1dFXycsIEVPVywgJy5jc3YnLHNlcCA9ICIiKSwgc2VwID0gJy8nICkpDQp3cml0ZV9jc3YoTW9udGhseV9CcmFuZF9Db21iaW5lLCANCiAgICAgICAgICBwYXRoID0gcGFzdGUoU09UX09UU19kaXJlY3RvcnksICANCiAgICAgICAgICAgICAgICAgICAgICAgcGFzdGUoJ01vbnRobHlfQnJhbmRfQ29tYmluZV9XRV8nLCBFT1csICcuY3N2JyxzZXAgPSAiIiksIHNlcCA9ICcvJyApKQ0Kd3JpdGVfY3N2KE1vbnRobHlfQ2F0ZWdvcnlfQ29tYmluZSwgDQogICAgICAgICAgcGF0aCA9IHBhc3RlKFNPVF9PVFNfZGlyZWN0b3J5LCAgDQogICAgICAgICAgICAgICAgICAgICAgIHBhc3RlKCdNb250aGx5X0NhdGVnb3J5X0NvbWJpbmVfV0VfJywgRU9XLCAnLmNzdicsc2VwID0gIiIpLCBzZXAgPSAnLycgKSkNCndyaXRlX2NzdihNb250aGx5X0dhcEluY19Db21iaW5lLCANCiAgICAgICAgICBwYXRoID0gcGFzdGUoU09UX09UU19kaXJlY3RvcnksICANCiAgICAgICAgICAgICAgICAgICAgICAgcGFzdGUoJ01vbnRobHlfR2FwSW5jX0NvbWJpbmVfV0VfJywgRU9XLCAnLmNzdicsc2VwID0gIiIpLCBzZXAgPSAnLycgKSkNCndyaXRlX2NzdihQcmVmZXJyZWRfVmVuZG9yX05ld19Db21iaW5lLCANCiAgICAgICAgICBwYXRoID0gcGFzdGUoU09UX09UU19kaXJlY3RvcnksICANCiAgICAgICAgICAgICAgICAgICAgICAgcGFzdGUoJ1ByZWZlcnJlZF9WZW5kb3JfTmV3X0NvbWJpbmVfV0VfJywgRU9XLCAnLmNzdicsc2VwID0gIiIpLCBzZXAgPSAnLycgKSkNCndyaXRlX2NzdihNb250aGx5X2J5X0RDLCANCiAgICAgICAgICBwYXRoID0gcGFzdGUoU09UX09UU19kaXJlY3RvcnksICANCiAgICAgICAgICAgICAgICAgICAgICAgcGFzdGUoJ01vbnRobHlfYnlfRENfV0VfJywgRU9XLCAnLmNzdicsc2VwID0gIiIpLCBzZXAgPSAnLycgKSkNCndyaXRlX2NzdihNb250aGx5X1RvcF8yMF9Db21iaW5lLCANCiAgICAgICAgICBwYXRoID0gcGFzdGUoU09UX09UU19kaXJlY3RvcnksICANCiAgICAgICAgICAgICAgICAgICAgICAgcGFzdGUoJ01vbnRobHlfVG9wXzIwX0NvdW50cmllc19XRV8nLCBFT1csICcuY3N2JyxzZXAgPSAiIiksIHNlcCA9ICcvJyApKQ0Kd3JpdGVfY3N2KE1vbnRobHlfVG9wXzUwX1ZlbmRvcnNfQ29tYmluZSwgDQogICAgICAgICAgcGF0aCA9IHBhc3RlKFNPVF9PVFNfZGlyZWN0b3J5LCAgDQogICAgICAgICAgICAgICAgICAgICAgIHBhc3RlKCdNb250aGx5X1RvcF81MF9WZW5kb3JzX1dFXycsIEVPVywgJy5jc3YnLHNlcCA9ICIiKSwgc2VwID0gJy8nICkpDQp3cml0ZV9jc3YoT1RTdnNTT1QsIA0KICAgICAgICAgIHBhdGggPSBwYXN0ZShTT1RfT1RTX2RpcmVjdG9yeSwgIA0KICAgICAgICAgICAgICAgICAgICAgICBwYXN0ZSgnT1RTdnNTT1RfV0VfJywgRU9XLCAnLmNzdicsc2VwID0gIiIpLCBzZXAgPSAnLycgKSkNCndyaXRlX2NzdihCcmFuZF9Ub3BfVGVuX0RlbGF5LCANCiAgICAgICAgICBwYXRoID0gcGFzdGUoU09UX09UU19kaXJlY3RvcnksICANCiAgICAgICAgICAgICAgICAgICAgICAgcGFzdGUoJ0JyYW5kX1RvcF8xMF9EZWxheV9XRV8nLCBFT1csICcuY3N2JyxzZXAgPSAiIiksIHNlcCA9ICcvJyApKQ0Kd3JpdGVfY3N2KENhdGVnb3J5X1RvcF9UZW5fRGVsYXksIA0KICAgICAgICAgIHBhdGggPSBwYXN0ZShTT1RfT1RTX2RpcmVjdG9yeSwgIA0KICAgICAgICAgICAgICAgICAgICAgICBwYXN0ZSgnQ2F0ZWdvcnlfVG9wXzEwX0RlbGF5X1dFXycsIEVPVywgJy5jc3YnLHNlcCA9ICIiKSwgc2VwID0gJy8nICkpDQoNCg0KYGBgDQoNCg==